Table of Contents
- Introduction
- What is a Monorepo?
- Benefits of Using a Monorepo for React Projects
- Turborepo vs Nx: Feature Comparison
- Setting Up a Monorepo with Turborepo
- Setting Up a Monorepo with Nx
- Organizing Apps, Packages, and Shared Libraries
- Using React, Tailwind, and Shared UI Components
- Build Caching, Task Pipelining, and Dependency Graphs
- Versioning and Publishing Packages
- Best Practices and Scaling Tips
- Conclusion
1. Introduction
As frontend projects grow more complex, developers often find themselves working on multiple apps (admin panel, landing page, dashboard) and packages (UI components, utilities, shared logic). Managing these in separate repositories becomes a nightmare. The solution? Monorepos.
This module covers the why, when, and how of using Turborepo or Nx to manage React apps and libraries within a single monorepo. You’ll learn how to share code, streamline builds, reduce duplication, and improve overall developer experience.
2. What is a Monorepo?
A monorepo (monolithic repository) is a single Git repository that contains multiple projects—apps, packages, libraries—all maintained together.
Examples:
apps/web
,apps/admin
,packages/ui
,packages/utils
3. Benefits of Using a Monorepo for React Projects
- Code Reuse: Share components, hooks, and utilities across apps.
- Single Source of Truth: All code lives together, easier to coordinate.
- Atomic Changes: Refactor across apps and packages in one commit.
- Optimized Builds: Tools like Turborepo and Nx enable smart caching and parallel builds.
- Developer Productivity: Better collaboration, fewer integration issues.
4. Turborepo vs Nx: Feature Comparison
Feature | Turborepo | Nx |
---|---|---|
Ecosystem | JavaScript-first (by Vercel) | Full-stack (JS, TS, Go, etc.) |
UI | Minimal CLI | Powerful GUI + CLI |
Build Cache | Local + Remote (via Vercel) | Local + Remote (via Nx Cloud) |
Dependency Graph | Yes | Yes + Visual Graph |
Community/Support | Lightweight, focused | Enterprise-grade, extensible |
Plugins for Frameworks | Manual setup | Built-in React, Next.js, Nest |
5. Setting Up a Monorepo with Turborepo
bashCopyEditnpx create-turbo@latest
Directory structure:
pgsqlCopyEditmy-turbo-repo/
├── apps/
│ ├── web/
│ └── admin/
├── packages/
│ ├── ui/
│ └── utils/
├── turbo.json
Install dependencies:
bashCopyEditcd my-turbo-repo
npm install
Example turbo.json
:
jsonCopyEdit{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "dist/**"]
},
"lint": {},
"test": {}
}
}
Run all builds:
bashCopyEditnpx turbo run build
6. Setting Up a Monorepo with Nx
bashCopyEditnpx create-nx-workspace@latest
Choose:
- Monorepo setup
- Add React when prompted
You’ll get:
perlCopyEditmy-nx-workspace/
├── apps/
│ ├── web/
├── libs/
│ ├── ui/
│ └── utils/
├── nx.json
Add another app:
bashCopyEditnx generate @nrwl/react:application admin
Add a shared lib:
bashCopyEditnx generate @nrwl/react:library ui
7. Organizing Apps, Packages, and Shared Libraries
Common structure:
markdownCopyEditapps/
- web/ → Main frontend app
- admin/ → Admin dashboard
packages/
- ui/ → Shared component library (Button, Modal)
- utils/ → Shared functions, hooks
- config/ → ESLint, Tailwind, Prettier
Importing shared packages:
tsxCopyEditimport { Button } from '@myorg/ui';
Use path aliases via tsconfig.json
.
8. Using React, Tailwind, and Shared UI Components
In your shared ui
package:
tsxCopyEditexport const Button = ({ children }) => (
<button className="bg-blue-500 px-4 py-2 rounded text-white">{children}</button>
);
Configure Tailwind in each app to use shared styles.
Make a tailwind-config
package and extend it:
jsCopyEdit// packages/tailwind-config/index.js
module.exports = {
theme: { extend: {} },
plugins: [],
};
In apps:
jsCopyEditconst config = require('@myorg/tailwind-config');
module.exports = {
presets: [config],
};
9. Build Caching, Task Pipelining, and Dependency Graphs
- Turborepo uses content-aware hashing and smart pipelines.
- Nx offers task orchestration and a visual graph (
nx graph
). - Both support remote caching to reuse builds across CI pipelines.
Example:
bashCopyEditnpx turbo run build --filter=web
10. Versioning and Publishing Packages
Use Changesets:
bashCopyEditnpm install @changesets/cli
npx changeset init
Automated version bumps, changelogs, and package publishing.
Or manually:
bashCopyEditcd packages/ui
npm version patch
npm publish --access public
11. Best Practices and Scaling Tips
- Use Yarn Workspaces or pnpm for faster dependency installs.
- Keep packages atomic and loosely coupled.
- Use Nx generators to automate common tasks.
- Separate CI/CD workflows for apps and packages.
- Integrate storybook in your UI library.
- Enforce linting and formatting at root with shared configs.
12. Conclusion
Monorepos streamline the development of large-scale React applications, allowing code sharing, better organization, and more efficient builds. With Turborepo or Nx, you gain powerful build tools, dependency graphs, and dev tooling to take your productivity to the next level.
Choose Turborepo if you prefer minimal setup and Vercel integration. Go with Nx if you want rich tooling, extensibility, and support for multiple frameworks.