
CI/CD in Monorepo Structure: Turborepo and GitHub Actions Integration
Managing multiple applications and packages in a single repository can turn into chaos without the right tools. Turborepo dramatically speeds up CI/CD processes in monorepo projects with its smart caching and task pipeline mechanism. This guide walks you through Turborepo setup, GitHub Actions integ
Can Kaya
Security Specialist
Managing multiple applications and packages in a single repository can turn into chaos without the right tools. Turborepo dramatically speeds up CI/CD processes in monorepo projects with its smart caching and task pipeline mechanism. This guide walks you through Turborepo setup, GitHub Actions integration, remote caching, and affected filtering step by step.
Monorepo vs Polyrepo Comparison
The choice between monorepo and polyrepo depends on team size, project structure, and deployment strategy. The table below summarizes the key differences.
| Feature | Monorepo | Polyrepo |
|---|---|---|
| Code sharing | Easy (internal packages) | Difficult (npm publish required) |
| CI/CD complexity | Medium (with affected filter) | Low (independent pipelines) |
| Dependency management | Centralized (single lock file) | Distributed (separate per repo) |
| Atomic changes | Possible with single PR | Multiple PRs required |
| Repo size | Large (all code in one place) | Small (isolated repos) |
💡 Tip: If you have 3+ applications and shared packages, a monorepo structure simplifies code sharing and version compatibility. Tools like Turborepo, Nx, or Lerna make this process manageable.
Turborepo Setup and Project Structure
Turborepo is a high-performance monorepo build system developed by Vercel. Creating a new project or adding it to an existing one is straightforward.
# Create a new monorepo project
npx create-turbo@latest my-monorepo
# Add Turborepo to an existing project
npm install turbo --save-dev
# Project structure
my-monorepo/
├── apps/
│ ├── web/ # Next.js frontend
│ ├── api/ # Express backend
│ └── admin/ # Admin panel
├── packages/
│ ├── ui/ # Shared UI components
│ ├── config/ # ESLint, TS config
│ └── utils/ # Common utility functions
├── turbo.json
├── package.json
└── pnpm-workspace.yaml
Define your workspace directories in pnpm-workspace.yaml:
packages:
- "apps/*"
- "packages/*"
Task Pipeline Configuration (turbo.json)
Turborepo's power comes from the task pipeline definitions in turbo.json. Each task's dependencies, outputs, and cache behavior are defined here.
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": ["**/.env.*local"],
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "!.next/cache/**", "dist/**"]
},
"test": {
"dependsOn": ["build"],
"inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**"]
},
"lint": {
"dependsOn": ["^build"]
},
"dev": {
"cache": false,
"persistent": true
}
}
}
⚠️ Warning: The ^build notation means "run the build task of dependencies first." This ensures packages/ui is built before apps/web. If the ordering is wrong, the build will fail.
GitHub Actions with Affected Filter
Building all applications on every push in a monorepo is wasteful. With Turborepo's --filter flag, you can build only the changed packages and their dependents.
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- uses: pnpm/action-setup@v3
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: "pnpm"
- run: pnpm install --frozen-lockfile
# Build only changed packages
- run: pnpm turbo build --filter=...[HEAD^1]
# Run tests for changed packages
- run: pnpm turbo test --filter=...[HEAD^1]
# Lint check
- run: pnpm turbo lint --filter=...[HEAD^1]
The --filter=...[HEAD^1] expression selects packages changed since the last commit and all packages that depend on them. In a monorepo with 10 applications, if only 2 changed, only those 2 get built.
Speeding Up Builds with Remote Caching
One of Turborepo's most powerful features is remote caching. When a developer or CI runner writes build output to the cache, another runner with the same input can skip the build entirely by using that cache.
jobs:
build:
runs-on: ubuntu-latest
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
- uses: actions/setup-node@v4
with:
node-version: 20
cache: "pnpm"
- run: pnpm install --frozen-lockfile
# Remote cache is automatically active
- run: pnpm turbo build test lint
💡 Tip: Remote caching reduces average CI times by 40-65%. Vercel Remote Cache is free to use, or you can set up a self-hosted cache server. Connect your account with turbo login and turbo link commands.
For CI/CD pipeline fundamentals, check our GitHub Actions CI/CD guide. For GitOps approach, see our ArgoCD guide. For deployment strategies, explore our Blue-Green and Canary Deployment guide. Turborepo Official Documentation and GitHub Actions Documentation are valuable additional resources.
Frequently Asked Questions
What is the difference between Turborepo and Nx?
Turborepo is lighter and easier to configure, focusing specifically on JavaScript/TypeScript projects. Nx offers a more comprehensive ecosystem with code generation and a plugin system supporting multiple languages. Turborepo is preferred for small-to-medium projects, while Nx suits large enterprise projects.
Can each application be deployed independently in a monorepo?
Yes, with Turborepo's filter mechanism you can build and deploy each application independently. Use commands like --filter=web to target a specific application.
Is remote caching secure?
Vercel Remote Cache stores artifacts encrypted and only authorized team members can access them. For self-hosted solutions, HTTPS and token-based authentication should be used.
Does Git performance degrade in a monorepo?
Git operations can slow down in large monorepos. Use Git sparse-checkout and shallow clone to pull only necessary directories in CI. Setting fetch-depth: 2 in GitHub Actions mitigates this issue.
Conclusion
The Turborepo and GitHub Actions combination makes CI/CD processes in monorepo projects fast, efficient, and manageable. Automate dependency ordering with task pipelines, skip unnecessary builds with affected filters, and dramatically reduce CI times with remote caching.
Fast Infrastructure for Monorepo CI/CD
Speed up your build and deploy processes with Hosted Cloud servers.
Explore Cloud Server Plans →Can Kaya
Security Specialist
CISSP-certified security expert creating content on cybersecurity, DDoS protection, and server hardening.
Comments coming soon