Back

Setting Up a Monorepo with Turborepo

A straightforward guide to setting up a monorepo using Turborepo

What You'll Build

A monorepo with:

  • Shared packages (UI components, utilities)
  • Multiple apps (web, docs)
  • Fast, cached builds

Quick Start

Create a new Turborepo project:

npx create-turbo@latest

Follow the prompts. It'll scaffold everything you need.

Project Structure

Your monorepo will look like this:

my-monorepo/
├── apps/
│   ├── web/          # Next.js app
│   └── docs/         # Another app
├── packages/
│   ├── ui/           # Shared UI components
│   └── config/       # Shared configs
├── package.json
└── turbo.json        # Turborepo config

Understanding turbo.json

This file controls your build pipeline:

{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "dist/**"]
    },
    "dev": {
      "cache": false
    },
    "lint": {}
  }
}
  • dependsOn: Run dependencies first
  • outputs: What files to cache
  • cache: Enable/disable caching

Adding a New Package

Create a new folder in packages/:

mkdir packages/utils
cd packages/utils
npm init -y

Add your code:

// packages/utils/index.js
export function formatDate(date) {
  return new Intl.DateTimeFormat("en-US").format(date);
}

Using Shared Packages

In your app's package.json:

{
  "dependencies": {
    "utils": "*"
  }
}

Then import it:

import { formatDate } from "utils";

Running Commands

Run commands across all packages:

# Build everything
npm run build

# Dev mode for all apps
npm run dev

# Run lint everywhere
npm run lint

Run for specific apps:

npm run build --filter=web

Why Turborepo Rocks

Caching: Turborepo caches everything. Second builds are instant.

Parallel execution: It runs tasks in parallel when possible.

Remote caching: Share cache with your team (optional).

Common Patterns

Shared TypeScript Config

// packages/config/tsconfig.json
{
  "compilerOptions": {
    "strict": true,
    "esModuleInterop": true
  }
}

Extend it in apps:

{
  "extends": "config/tsconfig.json"
}

Shared ESLint Config

Similar pattern - create a config package and extend it.

Tips

  • Keep packages small and focused
  • Use workspace protocol: "package-name": "workspace:*"
  • Don't over-engineer - start simple
  • Let Turborepo handle the complexity

Next Steps

  • Add remote caching for teams
  • Set up CI/CD pipelines
  • Explore task dependencies
  • Check out the Turborepo docs
Setting Up a Monorepo with Turborepo | Loggrfun