🏗️ Monorepo Name
A full-stack monorepo containing web app, API, and shared packages.
📑 Table of Contents
- About
- How It Works
- Real-World Use Cases
- What's Inside
- Prerequisites
- Getting Started
- Usage
- Workspace Structure
- Shared Packages
- Available Scripts
- Adding a New App or Package
- CI/CD
- Contributing
- License
🧾 About
Tagline — One sentence describing what lives in this monorepo.
2–3 sentences: what products or services this repo contains, why a monorepo was chosen, and who manages it.
Example:
This monorepo houses the full platform for ProductName — including the customer-facing Next.js web app, the internal admin dashboard, and the shared Fastify API. A monorepo keeps shared types, UI components, and configs in sync across all products without publishing separate npm packages for every change.
⚙️ How It Works
pnpm install (hoisted dependencies at root)
│
▼
Turborepo reads turbo.json (pipeline config)
│
├── build → runs in dependency order
├── test → runs in parallel
└── lint → runs in parallel
Remote Cache stores task outputs → skips unchanged work on CI
- Dependency Hoisting: pnpm installs all packages from a single lockfile, deduplicating shared deps.
- Task Pipeline: Turborepo knows which apps depend on which packages and runs builds in the correct order.
- Remote Caching: Outputs are cached remotely — if nothing changed, tasks complete in milliseconds on CI.
- Cross-package imports: Internal packages are referenced via
workspace:*
and resolved locally — no publishing required.
💼 Real-World Use Cases
- Product Companies: One repo for the marketing site, app, API, and internal tools. A single PR can update shared types and all consumers in one commit.
- Design System Teams: Ship the component library alongside the products that use it. Breaking changes in the library surface as CI failures in consuming apps before merge.
- Agencies with Multiple Clients: Shared config (ESLint, TypeScript, Tailwind presets) lives in
packages/config
and is consumed by each client project — one update propagates everywhere.
📦 What's Inside
Apps
| App | Description | Port |
|---|---|---|
web | Next.js frontend | 3000 |
api | Fastify backend API | 4000 |
admin | React admin dashboard | 3001 |
docs | Nextra documentation site | 3002 |
Packages
| Package | Description |
|---|---|
@repo/ui | Shared React component library |
@repo/config | Shared ESLint and TypeScript configs |
@repo/types | Shared TypeScript types |
@repo/utils | Shared utility functions |
@repo/db | Prisma client and schema |
📋 Prerequisites
- Node.js ≥ 18
- pnpm ≥ 9 — install with
npm install -g pnpm
- Docker (for local databases)
🏁 Getting Started
git clone https://github.com/username/monorepo.git cd monorepo pnpm install pnpm dev # Starts all apps concurrently
💡 Usage
Run a specific app
pnpm dev --filter web # Only the Next.js app pnpm dev --filter api # Only the API pnpm build --filter web # Build only the web app
Add a dependency to one app
pnpm add lodash --filter web
Add a shared internal package to an app
In
apps/web/package.json:
{
"dependencies": {
"@repo/ui": "workspace:*"
}
}
Then run
pnpm installfrom the root.
Use a shared component
import { Button, Card } from "@repo/ui";
export default function Page() {
return (
<Card>
<Button variant="primary">Click me</Button>
</Card>
);
}
📂 Workspace Structure
monorepo/ ├── apps/ │ ├── web/ │ ├── api/ │ ├── admin/ │ └── docs/ ├── packages/ │ ├── ui/ │ ├── config/ │ ├── types/ │ ├── utils/ │ └── db/ ├── turbo.json ├── pnpm-workspace.yaml └── package.json
📜 Available Scripts
| Script | Description |
|---|---|
pnpm dev | Start all apps in dev mode |
pnpm build | Build all apps and packages |
pnpm test | Run tests across all workspaces |
pnpm lint | Lint all workspaces |
pnpm format | Format all files with Prettier |
pnpm dev --filter web | Start only the web app |
➕ Adding a New App or Package
# Scaffold a new app mkdir apps/my-new-app && cd apps/my-new-app && pnpm init # Create a new package mkdir packages/my-package && cd packages/my-package && pnpm init
🔁 CI/CD
# Only builds and tests what changed - run: pnpm turbo build test lint --filter=[HEAD^1]
Remote caching is configured via Vercel Remote Cache.
🤝 Contributing
Read CONTRIBUTING.md. All changes must pass CI before merging.
📝 License
Distributed under the MIT License. See LICENSE for more information.
README Templates FAQ
Common questions about using our GitHub README templates.