How to Use Turborepo: The Beginner's Guide to Monorepo Builds, Caching, and Remote Cache

CodexFuse Team · 2026-10-31T03:57:27.257Z · 10 min read

Turborepo is the build system for JavaScript and TypeScript monorepos. Learn how to scaffold with create-turbo, configure turbo.json tasks, use caching and --filter, and share the cache with Remote Caching.

What is Turborepo, and why does your monorepo need it?

Turborepo is a build system for JavaScript and TypeScript monorepos that makes running tasks across many packages dramatically faster by scheduling them intelligently, running them in parallel, and caching every result. This beginner's guide shows you how to use Turborepo from zero: scaffold a monorepo with create-turbo, define tasks in turbo.json, watch your first cache hit skip the work entirely, target single packages with --filter, and share the cache with your whole team through Remote Caching.

The problem Turborepo solves is monorepo scale. Each workspace in a monorepo has its own test suite, its own linting, and its own build process — the official Turborepo documentation notes that a single monorepo can contain thousands of tasks to execute. Its own illustration walks through a small example: three workspaces taking 110, 140, and 90 seconds on their first run, and finishing in about 80 milliseconds once the cache kicks in. Without a build system coordinating this, every package rebuilds everything it needs from scratch, every time, on every machine.

Vercel builds and maintains Turborepo, and the current documentation (updated 2026-10-27) now describes it as "the build system for coding agents" — a sign of where its development effort is aimed. It is designed to be adopted incrementally: it takes minutes to add, reuses the package.json scripts you already wrote, adds a single turbo.json configuration file, and works with npm, yarn, pnpm, or bun. Where the build time goes in a monorepo is usually CI, and the GitHub Actions workflow generator is the companion tool for the CI pipeline you will wire Turborepo into later in this guide.

What do you need before you start?

You need Node.js installed and a package manager you are comfortable with — npm, pnpm, yarn, or bun. If you are new to the pnpm world, create-turbo itself recommends pnpm when you are unsure, and you can install it in one command before starting. Check node -v in your terminal so you are not debugging a cryptic scaffold failure on an ancient Node.

You do not need a global turbo install to begin. The scaffold command runs through your package manager's dlx runner, and Turborepo can later be pinned per-repository as a devDependency. A Git repository is expected — the scaffold offers to initialize one for you — because Turborepo reads your lockfile to build its package graph. The package.json generator is handy if you want to understand the workspace fields you are about to see in the root package.json.

How do you create your first Turborepo?

You create your first Turborepo with the official scaffold CLI, create-turbo, which generates a working monorepo you can learn on. Run the command for your package manager, answer two questions, and you get a complete project with apps, shared packages, and a working turbo.json. It takes under a minute.

  1. Run the scaffold. With pnpm: pnpm dlx create-turbo@latest. Equivalents: npx create-turbo@latest for npm, yarn dlx create-turbo@latest for yarn, bunx create-turbo@latest for bun. Per the Turborepo installation docs, this exact set of commands is current as of 2026-10-27.
  2. Answer the prompts. The scaffold asks where to create your monorepo (the default is ./my-turborepo) and which package manager to use (npm, pnpm, or yarn). If you are not sure, the scaffold itself recommends pnpm.
  3. Inspect what it made. The starter repository ships with two deployable applications and three shared libraries for use across the rest of the monorepo, per the installation docs. A real scaffold transcript (create-turbo 1.6.3) shows the concrete layout: apps/web (a Next.js app with TypeScript), apps/docs (a second Next.js app), packages/ui (a shared React component library), packages/eslint-config-custom (shared ESLint configuration), and packages/tsconfig (shared TypeScript tsconfig.json).
  4. Install dependencies. The scaffold installs them for you; if it did not, run your package manager's install command inside the new directory.
  5. Optionally install turbo globally. A global install brings turbo to any terminal: on macOS and Linux run curl -fsSL https://turborepo.dev/install | sh, on Windows x64 run irm https://turborepo.dev/install.ps1 | iex in PowerShell. Binaries are also published directly in the GitHub release assets starting with version 2.11.5.

How do the apps and packages fit together?

A Turborepo monorepo is organized around workspaces — folders that each contain a package.json. Each workspace declares its own dependencies, runs its own scripts, and can export code for the others. The two folder types follow one simple rule: apps/ holds things you deploy, packages/ holds things you share.

PathWhat it is
apps/web, apps/docsDeployable applications. Each has its own build, dev, and lint scripts — these are the scripts Turborepo will run for you.
packages/uiA shared React component library. Both apps import it, so one design system serves every app in the repo.
packages/eslint-config-customShared lint configuration. One config file, applied to every workspace — change it once and the whole repo lints the same way.
packages/tsconfigShared TypeScript configuration that the apps extend. If your TypeScript is shaky, the TypeScript cheat sheet covers the syntax you will see in these config files.
turbo.jsonThe single root configuration file that registers tasks and tells Turborepo how they depend on each other.

The power of the layout is visible in imports: apps/web can import a button from @repo/ui without copying any files, and a change to that button propagates to every app on the next build. This is the core monorepo idea — Turborepo's job is making it fast.

What is turbo.json and how do tasks work?

turbo.json is the file that turns a pile of workspaces into a build system. In it, you register named tasks (build, test, lint, dev), and for each one you declare its dependencies, its outputs, and its environment variables. A task must be registered in turbo.json before Turborepo will run it — if it is not registered, turbo build will not touch it.

{
  "$schema": "https://turborepo.dev/schema.json",
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "dist/**"]
    },
    "test": {
      "dependsOn": ["^build"],
      "outputs": ["coverage/**"]
    },
    "lint": {},
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

Read it line by line: the build task depends on ^build, which means "build my dependencies first, then build me" — that caret is the dependency-order magic. Its outputs list tells Turborepo which files the build produces, so the cache knows what to save and restore. dev sets cache: false because a long-running dev server has no output to cache. One warning for beginners: many older guides still show a pipeline key in turbo.json — that key is deprecated in favor of tasks, and copying a stale config from an old post is the most common beginner breakage in the wild.

For a single command, Turborepo resolves the full task graph: it reads your lockfile and workspace package.json files to learn which packages depend on which, then schedules the registered tasks across all available cores. The default concurrency is 10 tasks at once, and you can raise or lower it in turbo.json. You can also use turbo.jsonc instead of turbo.json if you want comments with IDE support.

How does Turborepo caching work?

Turborepo caching means never doing the same work twice. For every task it runs, Turborepo fingerprints the inputs — your source files, your lockfile, the task's configuration, and, in strict mode, exactly the environment variables you declared — then stores the outputs it produced. Run the same task again with unchanged inputs and Turborepo restores the saved outputs instead of executing anything.

You will see this in the terminal as two distinct messages: a first run prints something like "cache miss, executing <hash>", and the second run prints "cache hit, replaying logs" and finishes in a blink. Try it right now in your scaffold: run turbo build twice in a row. The first run takes the normal build time; the second run completes almost instantly because every task was served from the local cache.

The local cache lives at .turbo/cache by default (configurable via cacheDir). To prove to yourself that caching is real, delete it — rm -rf ./.turbo/cache on macOS/Linux, or rd /s /q "./.turbo/cache" on Windows — and run turbo build again: the work runs for real this time. Two defaults worth knowing: environment variable handling is strict by default, so undeclared variables are invisible to tasks (this prevents a leaked secret from changing your cache fingerprint silently), and you can cap the cache with cacheMaxAge and cacheMaxSize in turbo.json.

How do you use --filter to build only what you need?

The --filter flag tells Turborepo to run a task in one package (and its dependencies) instead of everywhere. If you only changed apps/web, running the whole monorepo's test suite is wasted time — turbo build --filter=web builds the web app and everything it depends on, and nothing else.

Before you run a filtered command on a big repo, preview it with --dry: turbo build --filter=docs --dry prints an outline of exactly which tasks Turborepo would run, without running anything. Filters accept package names and can match dependents and dependencies, which is why this is the flag that makes CI fast: instead of one CI job running everything, each job runs turbo build --filter=... for the piece it owns. Turborepo also supports automatic package scoping — change into a package directory and run the task bare: cd apps/docs && turbo build runs the build script in the docs package and its dependencies.

What is Remote Caching and should you turn it on?

Remote Caching solves the one gap in local caching: the cache is local to your machine. Without it, you, your teammates, and your CI server each rebuild the same unchanged packages — duplicated work across the whole organization. A remote cache is a shared server that stores task results, so the first person to run a task uploads the result and everyone else downloads it.

You do not need Remote Caching to start with Turborepo — the docs say so explicitly — but it delivers the biggest speedups, and it is free. Vercel's managed Remote Cache is free on all plans, even if you do not host your applications on Vercel. To enable it for local development: authenticate with turbo login, then connect the repository with turbo link. After that, running tasks stores artifacts both locally and in your Remote Cache.

If you would rather own the server, self-hosting is supported: turbo login --manual takes the API URL, team, and token of your own cache, and the docs list community open-source implementations including brunojppb/turbo-cache-server, ducktors/turborepo-remote-cache, and Tapico/tapico-turborepo-remote-cache. One caution straight from the docs: Turborepo treats console logs as artifacts, so be aware of what your tasks print — and you can sign artifacts with an HMAC-SHA256 secret via remoteCache.signature and the TURBO_REMOTE_CACHE_SIGNATURE_KEY environment variable so downloaded results are verified as authentic.

How do you wire Turborepo into CI?

CI is where Turborepo earns its keep, because CI is where the same unchanged packages get rebuilt on every pull request. The setup has three parts: install the turbo binary in the CI environment (the global installer or a pinned devDependency, which the global binary defers to), pass the Remote Cache credentials as environment variables, and run your tasks with --filter so each job does only its own work. The GitHub beginner guide covers the GitHub side — repositories, branches, and pull requests — that this pipeline plugs into.

For debugging CI behavior without waiting for a run, Turborepo also supports package-level configuration files: a turbo.json inside a package directory with "extends": ["//"] inherits the root configuration and overrides just the tasks it needs. And remember that caching correctness matters more in CI than anywhere else: in strict env mode, declare every environment variable a task depends on in its env key, or CI will serve you cache hits built with different variables.

Turborepo vs Nx: which should a beginner pick?

The honest answer: for a JavaScript beginner building a first monorepo, Turborepo is the shorter path to a working, cached build. Nx is a more complete platform — project scaffolding, plugins, and an opinionated graph it manages for you — while Turborepo is a build system that layers onto the workspaces and scripts you already have. Here is how they compare on the things a beginner actually feels.

Decision pointTurborepoNx
What it isA task runner and cache for monorepos. It orchestrates your existing package.json scripts.A full dev toolkit: generators, plugins, and a task graph it helps you author.
Setup on an existing repoInstall turbo, add one turbo.json, go. Adopts incrementally in minutes.Heavier: the repo adopts Nx's structure and conventions.
CachingLocal + remote caching of task outputs; cache-hit replays are the headline feature.Also has local and distributed caching, plus its computation cache.
Configuration styleOne JSON file with task definitions (dependsOn, outputs, env).Configuration plus a plugin/graph model; more knobs, more learning.
Remote cacheFree managed option via Vercel, or self-hosted servers.Managed option via Nx Cloud, or self-hosted.
Code generatorsturbo generate adds new code; basic compared to Nx.Rich generators and migrations are a core selling point.
Learning curveLow: learn turbo.json and you are productive.Medium: the framework itself is a subject to learn.
Best forTeams who want their existing scripts to run fast, now.Teams who want an opinionated, guided monorepo platform.

This table is CodexFuse's own analysis based on the two tools' documented feature sets — treat it as a decision aid, not a benchmark. Pick Turborepo when you want the thinnest layer between your scripts and speed; pick Nx when you want the tool to also teach you how to structure the monorepo. Either way, do not split "turborepo vs nx" into its own article: it is a comparison question that belongs on this one page, which is why it lives here.

How do you add Turborepo to an existing repository?

You add Turborepo to an existing repository in three steps, and you do not need the scaffold. First, pin the turbo version as a devDependency at the root — with pnpm: pnpm add turbo --save-dev --ignore-workspace-root-check; with npm: npm install turbo --save-dev. When a local binary is installed, the global binary defers to it, so every contributor uses the pinned version.

Second, write your turbo.json. Start with the tasks you actually run today — build, test, lint — register each under tasks, give build its dependsOn: ["^build"] and its outputs, and skip cache: false entries for dev servers. Third, point your root scripts at it: "build": "turbo run build". Turborepo reads your existing workspace layout and lockfile, so there is no migration of the code itself. The git command generator can produce the init-and-first-commit commands if your repo is not under version control yet — Turborepo works best with Git history it can read.

Sources

All facts in this article were verified against the pages below on 2026-10-30. The Turborepo documentation pages were last updated 2026-10-27. Claims about the field's age and content are CodexFuse's SERP observations from 2026-10-30, which found only guide/explainer articles and documentation mirrors — zero tool pages — for the target queries.

  • Turborepo official documentation — Introduction: "the build system for coding agents"; monorepos with thousands of tasks; the 110s/140s/90s illustration vs ~80ms cached; incremental adoption in minutes; single turbo.json; npm, yarn, pnpm, bun support. https://turbo.build/docs
  • Turborepo official documentation — Installation (lastUpdated 2026-10-27): pnpm dlx create-turbo@latest (npx, yarn dlx, bunx equivalents); starter = two deployable applications + three shared libraries; global install via curl -fsSL https://turborepo.dev/install | sh (macOS/Linux) and irm https://turborepo.dev/install.ps1 | iex (Windows x64); GitHub release binaries from 2.11.5; turbo is an alias for turbo run; turbo build --filter=docs --dry; automatic package scoping via cd apps/docs && turbo build; turbo generate. https://turbo.build/docs/getting-started/installation
  • Turborepo official documentation — Configuring turbo.json (lastUpdated 2026-10-27): tasks key (replaces the deprecated pipeline key); cacheDir default .turbo/cache; envMode default strict; concurrency default 10; turbo.jsonc for comments; package configs with "extends": ["//"]; remoteCache.signature with TURBO_REMOTE_CACHE_SIGNATURE_KEY. https://turbo.build/docs/reference/configuration
  • Turborepo official documentation — Remote Caching (lastUpdated 2026-10-27): cache is local by default; Remote Caching free; Vercel managed cache free on all plans even without Vercel hosting; turbo login + turbo link; self-hosting via turbo login --manual; community implementations (brunojppb/turbo-cache-server, ducktors/turborepo-remote-cache, Tapico/tapico-turborepo-remote-cache); verify with rm -rf ./.turbo/cache; logs treated as artifacts; HMAC-SHA256 artifact signing. https://turbo.build/docs/core-concepts/remote-caching
  • Botmonster — "Monorepo Management with Turborepo: A Practical Guide" (~166 days old): practical guide with two apps plus shared UI/config packages; caching first; --filter for CI; Boundaries at scale. https://botmonster.com/web-dev/monorepo-management-turborepo-practical-guide/
  • dev.to (kcltech) — beginner monorepo explainer (~75 days old) with a minimal turbo.json tasks example. https://dev.to/kcltech/how-monorepos-work-a-beginner-friendly-guide-to-monorepos-400g
  • Reintech — "Turborepo Setup Guide: Build Faster Monorepos with TypeScript" (~139 days old): TypeScript setup walkthrough; --filter syntax; GitHub Actions CI example. https://reintech.io/blog/turborepo-complete-monorepo-setup-guide
  • Cedric Chee — "Creating a new monorepo with Turborepo": create-turbo 1.6.3 transcript — the two prompts (location default ./my-turborepo; package manager npm/pnpm/yarn with pnpm recommended) and the concrete starter contents (apps/web, apps/docs, packages/ui, packages/eslint-config-custom, packages/tsconfig). https://cedricchee.com/blog/turborepo-monorepo/

Frequently Asked Questions

Do I need workspaces set up before using Turborepo?

Turborepo works with your package manager's workspaces — it reads the workspace layout and lockfile to build its package graph, it does not replace them. If you can run pnpm install at the root and your packages link to each other, Turborepo has what it needs. The create-turbo scaffold sets all of this up for you.

What happened to the "pipeline" key in turbo.json?

It was renamed to tasks. The old pipeline key is deprecated, so any guide still showing it is stale — verify configs against the current turbo.build documentation. The semantics moved over: your task names, dependsOn, outputs, and env all live under tasks now.

Is Remote Caching really free?

Yes. Vercel's managed Remote Cache is free on all plans, even if you do not host your applications on Vercel — run turbo login and turbo link. If you want your own server instead, turbo login --manual connects to a self-hosted cache, including the community open-source implementations listed in the Sources section. You can also skip Remote Caching entirely; local caching alone is already a big win.

How do I clear the Turborepo cache?

Delete the cache directory: rm -rf ./.turbo/cache on macOS/Linux, or rd /s /q "./.turbo/cache" on Windows. The next turbo run will be a full cache miss and do the work for real. This is also the standard way to verify Remote Caching is working — clear the local cache, run the build, and confirm the artifacts download instead of executing.

Turborepo or Nx for a small team?

For a small team with existing package.json scripts, Turborepo is the faster win: install it, write one turbo.json, and your scripts run in parallel with caching. Choose Nx when you want an opinionated platform that also generates and structures the code for you. The full comparison table is in the "Turborepo vs Nx" section above.

Featured on Twelve Tools Launch Llama Tools Launch your MCP