NestJS + React + Vite + Tailwind + Turbo Template
This repository is a full-stack monorepo template using npm workspaces and Turborepo to manage a React frontend and a NestJS backend in a single repository.
The goal of this template is to provide:
- A minimal but correct monorepo setup
- Clear separation of frontend and backend concerns
- Centralized dependency management
- Coordinated development scripts without over-engineering
This is a template, not a production-ready system.
.
├── apps/
│ ├── backend/ # NestJS backend application
│ └── frontend/ # React + Vite + Tailwind frontend
├── packages/ # Optional shared packages (empty by default)
├── package.json # Root workspace + Turbo configuration
├── package-lock.json # Single lockfile for the entire monorepo
├── turbo.json # Turbo task pipeline
└── README.md
- This is a monorepo
- Dependency management is centralized at the root
- Each app remains a standalone project
- No code is shared by default
- Shared packages are optional, not assumed
- NestJS
- TypeScript
- Basic “Hello World” API
- React
- Vite
- TailwindCSS
- TypeScript
- npm workspaces (monorepo management)
- Turborepo (task orchestration and caching)
You need:
- Node.js (LTS recommended)
- npm (v7+ required for workspaces)
From the repository root:
npm installThis installs dependencies for all workspace packages and generates a single package-lock.json.
Do not run npm install inside individual apps.
Create a .env file in the apps/backend directory and add the following:
PORT=3000
FRONTEND_URL=http://localhost:5173
Variable Descriptions:
PORT
The port on which the backend server will run.
FRONTEND_URL
The URL of the frontend application.
Used for CORS configuration and client–server communication during development.
Run all development servers concurrently:
npm run devThis command:
- Uses Turbo to run the
devscript in each app - Starts the NestJS backend
- Starts the Vite frontend
- Streams logs with app prefixes
- Backend:
http://localhost:3000 - Frontend:
http://localhost:5173
To build all apps:
npm run buildTurbo will:
- Run builds in the correct order
- Cache outputs for faster rebuilds
- Skip unchanged packages when possible
To lint all packages:
npm run lintEach app is responsible for defining its own lint configuration.
Even though this is a monorepo:
- Frontend and backend do not depend on each other
- They can be deployed independently
- They can be developed in isolation
- No API client or shared types are included by default
If you want frontend ↔ backend communication, you must:
- Configure CORS in the backend
- Add environment variables in the frontend
- Implement API calls manually
This is intentional.
Turbo is configured via turbo.json and operates on script names, not commands.
If an app does not define a script (e.g. dev, build, lint), Turbo will skip it.
Turbo is used only for:
- Task orchestration
- Caching
- Parallel execution
It does not manage dependencies or enforce architecture.