As a codebase grows into a monorepo — several apps and shared packages in one repository — builds get slow. Rebuilding everything on every change wastes minutes you don't have, especially in a deployment pipeline. **Turborepo** fixes that by understanding the dependency graph between your packages, running tasks in parallel, and caching results so nothing is ever built twice unnecessarily. This guide covers setting up Turborepo and deploying a monorepo app with DeployHQ.

## What Turborepo does

Turborepo is a build orchestrator for JavaScript and TypeScript monorepos. It doesn't replace your bundler or test runner — it coordinates them. Given a set of tasks (build, test, lint) across many packages, it figures out the correct order from your dependency graph, runs independent work in parallel, and caches each task's output. Change one package and Turborepo rebuilds only that package and the things that depend on it; everything else is restored from cache instantly.

It sits on top of your existing workspace setup — npm, Yarn, or pnpm workspaces — and adds the orchestration layer.

## Setting up a workspace

Turborepo works with any workspace manager. pnpm workspaces are a common pairing; you declare your packages in `pnpm-workspace.yaml`:

```yaml
packages:
  - "apps/*"
  - "packages/*"
```

Then add Turborepo to the repo root:

```bash
pnpm add turbo -w -D
```

## Defining the task pipeline

Turborepo is configured with a `turbo.json` at the root. Each task declares what it depends on and what output it produces:

```json
{
  "$schema": "https://turbo.build/schema.json",
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**"]
    },
    "test": {
      "dependsOn": ["build"]
    },
    "lint": {}
  }
}
```

The `^build` in `dependsOn` means "build this package's dependencies first." `outputs` tells Turborepo which files to cache after a successful run. Now a single command builds the whole graph in the right order:

```bash
turbo build              # build everything, in dependency order
turbo run build test     # run multiple tasks
turbo build --filter=web # build just the "web" app and its deps
```

## Caching is the payoff

The first `turbo build` runs normally. The second — if nothing changed — completes in milliseconds, replayed from cache. In a pipeline, that means a docs-only change doesn't rebuild your API, and a shared-package change rebuilds only the apps that actually use it. Turborepo also supports remote caching so the cache is shared across machines and CI runs, but local caching alone already removes most redundant work.

## Deploying a monorepo with DeployHQ

The monorepo challenge for deployment is "build and ship only the app that changed, not the whole repo." Turborepo's `--filter` flag is exactly that lever.

In your [build pipeline](https://www.deployhq.com/features/build-pipelines), install dependencies and build the target app:

```bash
pnpm install
turbo build --filter=web
```

Then point the deployment at that app's build output (for example `apps/web/dist`) so only the compiled app ships. Enable [automatic deployments](https://www.deployhq.com/features/automatic-deployments) so each push builds the affected app and deploys it — the dependency graph decides what needs rebuilding, and DeployHQ ships the result.

Because the build runs on Node, set your Node version in your build configuration to match what your team develops against — the same version you'd pin locally with a [Node.js version manager like fnm or Volta](https://www.deployhq.com/guides/node-version-managers).

## Turborepo and your task runner

Turborepo orchestrates *cross-package* tasks and caching. For the everyday project commands a single developer runs — start the dev server, run a migration, seed the database — a lighter [command runner like just](https://www.deployhq.com/guides/just) pairs well: Turborepo for the monorepo graph, just for the day-to-day menu.

Ready to ship your monorepo without rebuilding everything each time? [Create a free DeployHQ account](https://www.deployhq.com/signup) and connect your repository in minutes.