If you're starting fresh today, I'd frame the decision like this:
- Turborepo: Great default if your stack is mostly JavaScript/TypeScript and you want fast builds with minimal configuration.
- Nx: Better if you expect a large codebase, many teams, complex dependency graphs, or you want stronger tooling around code generation and architecture.
- Something simpler (npm/pnpm workspaces + a task runner): Often the best choice if you only have a handful of packages and don't yet need advanced features.
For a typical app with:
apps/web (React/Next/Vite)
apps/api (Node/Nest/Fastify/Express)
packages/ui
packages/shared
packages/config
I'd probably start with pnpm workspaces + Turborepo.
Turborepo
Pros
- Very easy to understand.
- Excellent caching and parallel execution.
- Great developer experience.
- Doesn't try to dictate project architecture.
- Works well with Next.js, Vite, React, Node, and TypeScript.
Cons
- Fewer built-in architectural features.
- Doesn't analyze dependency relationships as deeply as Nx.
- You assemble more of your own tooling.
Typical commands stay simple:
turbo dev
turbo build
turbo test
turbo lint
For many startups and small-to-medium teams, that's enough.
Nx
Pros
- Excellent dependency graph.
- Affected builds/tests are very sophisticated.
- Generators/scaffolding can save lots of repetitive work.
- Strong enforcement of boundaries between packages.
- Good when many developers are working simultaneously.
Cons
- Steeper learning curve.
- More concepts to understand.
- Can feel heavy for a small project.
- Sometimes you end up learning Nx as much as your own project.
If your company eventually grows to dozens of libraries and multiple frontend/backend apps, Nx starts to shine.
Just workspaces
People often underestimate how far this goes.
apps/
web/
api/
packages/
ui/
shared/
Using:
- pnpm workspaces
- TypeScript project references
- ESLint
- Prettier
- Vitest/Jest
gets surprisingly far.
You can always add Turborepo later with relatively little disruption.
Common regrets I've seen
1. Making every little thing a package
Early monorepos often end up like:
packages/
strings/
colors/
dates/
logging/
validation/
formatting/
helpers/
types/
Now every change requires updating multiple packages.
Instead, start with fewer, larger packages.
2. Sharing too much
It's tempting to put everything into shared.
Instead of:
shared/
prefer clearer ownership:
packages/
ui/
database/
api-types/
auth/
Packages should have a clear purpose.
3. Tight frontend/backend coupling
Example:
Frontend imports backend implementation code.
Bad:
frontend
-> backend
Better:
frontend
-> api-types
backend
-> api-types
Share contracts, not implementations.
4. Premature micro-packaging
People split code into 25 packages because they might publish them someday.
Most never get published.
Optimize for your current team, not hypothetical future reuse.
5. Complicated CI
One huge pipeline that rebuilds everything every push gets slow quickly.
Good monorepo tooling (Turbo or Nx) helps by running only what changed.
A practical starting structure
apps/
web/
api/
packages/
ui/
shared/
config/
types/
package.json
pnpm-workspace.yaml
turbo.json
tsconfig.base.json
This scales well before needing additional complexity.
When I'd choose each
Choose Turborepo if:
- 2–20 developers.
- Mostly TypeScript.
- One frontend and one backend.
- You want minimal ceremony.
Choose Nx if:
- Multiple teams own different parts of the repository.
- Many applications and libraries.
- You value architectural enforcement and generators.
- Build performance at large scale is a major concern.
Choose just workspaces if:
- It's a side project or MVP.
- Fewer than about five packages.
- You don't yet know how the project will evolve.
Overall recommendation
For a new full-stack TypeScript project with a frontend, backend, and a few shared packages, I'd start with pnpm workspaces + Turborepo. It strikes a good balance between simplicity and scalability, and if your project eventually outgrows it, moving to Nx later is generally more manageable than starting with a heavyweight setup before you need it.