Ga naar inhoud
·1 min

Monorepo's met Turborepo: een praktische gids

Hoe ik mijn projecten organiseer met Turborepo, pnpm workspaces en gedeelde configuratie. Inclusief tips voor CI/CD.

ToolingDevOpsTutorial

Waarom een monorepo?

Toen ik begon met het bouwen van meerdere gerelateerde websites, stond ik voor een keuze: aparte repositories of een monorepo. Na ervaring met beide benaderingen kies ik tegenwoordig bijna altijd voor een monorepo.

De voordelen

  • Gedeelde code: UI componenten, configuratie en utilities op één plek
  • Atomic changes: Wijzigingen die meerdere packages raken in één commit
  • Consistente tooling: Eén ESLint config, één TypeScript setup, één CI pipeline

De structuur

Mijn typische monorepo structuur ziet er zo uit:

├── apps/
│   ├── personal/     # Next.js app
│   ├── business/     # Next.js app
│   └── commandhub/   # Next.js app
├── packages/
│   ├── ui/           # Gedeelde componenten
│   ├── email/        # E-mail utilities
│   ├── config-tailwind/
│   ├── config-typescript/
│   └── config-eslint/
├── turbo.json
└── pnpm-workspace.yaml

pnpm Workspaces

pnpm is mijn package manager van keuze voor monorepos. Het is sneller dan npm en yarn, en de workspace support is uitstekend.

# pnpm-workspace.yaml
packages:
  - "apps/*"
  - "packages/*"

Packages refereren naar elkaar met workspace:*:

{
  "dependencies": {
    "@steding/ui": "workspace:*",
    "@steding/email": "workspace:*"
  }
}

Turborepo configuratie

De turbo.json definieert je build pipeline en caching strategie:

{
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "dist/**"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

Het ^build patroon zorgt ervoor dat dependencies eerst worden gebuild. De outputs array vertelt Turbo welke bestanden gecached moeten worden.

Tips voor de praktijk

1. Gebruik JIT compilatie voor UI packages

In plaats van je UI package te builden, kun je Next.js het direct laten transpileren:

// next.config.ts
const nextConfig = {
  transpilePackages: ["@steding/ui"],
};

Dit bespaart een build stap en maakt de developer experience veel sneller.

2. Gedeelde configuratie als packages

Maak aparte packages voor ESLint, TypeScript en Tailwind configuratie. Elke app extendst dan simpelweg de gedeelde config.

3. Turbo cache in CI

Turborepo's remote caching kan je CI builds dramatisch versnellen. Als alleen de personal site is veranderd, hoeft de business site niet opnieuw gebuild te worden.

Conclusie

Een monorepo met Turborepo en pnpm is een krachtige combinatie voor teams die meerdere gerelateerde projecten beheren. De initiële setup kost wat tijd, maar de tijdwinst op de lange termijn is enorm.

Plan een gesprek