//

Turborepo: The Next Big Thing in Build Systems

Turborepo is a high-performance build system for JavaScript and TypeScript codebases. Vercel who acquired Turborepo claims, through incremental builds, intelligent remote caching, and optimized task scheduling, Turborepo can boost build speeds by 85% or more, enabling teams of all sizes to maintain a fast and efficient build system that scales as codebases and teams grow.

What is a monorepo?

A monorepo (mono repository) is a single repository that stores all of your code and assets for every project. These include your frontend as well as backend code.

The benfits of a monorepo are:

  • A single source of truth. (e.g. dependency management with a single package.json file, tests and configs)
  • Share and reuse code easily.
  • Visibility to manage dependencies (e.g., if you make a change, what else will be impacted?).
  • To make atomic changes (e.g., one operation to make a change across multiple projects).
  • Ease of teams to collaborate more.
  • For making large-scale changes (e.g., code refactoring).

This seems to be the trend with companies like Google and Facebook.

What is Turborepo?

Monorepos are incredible for productivity, especially on the frontend, but the tooling can be a nightmare. There’s a lot of stuff to do (and things to mess up). Nothing “just works.” It’s become completely normal to waste entire days or weeks on plumbing — tweaking configs, writing one-off scripts, and stitching stuff together.

According to Jared Palmer the founder of Turborepo, it is a fresh take on the whole tooling setup. Designed to glue everything together. A toolchain with sensible defaults, but even better escape hatches. Built with the same techniques used by the big guys, but in a way that doesn’t require staff to maintain.

Turborepo is a high-performance build system for JavaScript and TypeScript codebases. Vercel who acquired Turborepo claims, through incremental builds, intelligent remote caching, and optimized task scheduling, Turborepo can boost build speeds by 85% or more, enabling teams of all sizes to maintain a fast and efficient build system that scales as codebases and teams grow.

What does Turborepo offer?

Turborepo reimagines build system techniques used by Facebook and Google to remove maintenance burden and overhead.

Incremental builds (cache artifacts)

By skipping the artifacts that have already been computed by building once, Turborepo will remember what you’ve built.

Content-aware hashing (contents not timestamps)

Turborepo looks at the contents of your files, not timestamps to figure out what needs to be built.

Remote Caching (Share build cache)

Share a remote build cache with your teammates and CI/CD for even faster builds.

Parallel execution (Maximise CPU usage)

Execute builds using every core at maximum parallelism without wasting idle CPUs.

Zero runtime overhead (Won’t interfere with your code)

Turborepo won’t interfere with your runtime code or touch your sourcemaps.

Pruned subsets (Speed up PaaS)

Speed up PaaS (Platform as a Service) deploys by generating a subset of your monorepo with only what’s needed to build a specific target.

Task pipelines (Task relationships)

Define the relationships between your tasks and then let Turborepo optimize what to build and when.

Profile in your browser (Generate build profiles)

Generate build profiles and import them in Chrome or Edge to understand which tasks are taking the longest.

Getting Started

Brand new monorepo

If you’re starting a brand new monorepo, you can get started with a single command.

npx create-turbo@latest

Follow the prompts to bootstrap a brand new Turborepo.

Bootstrap a brand new Turborepo

yarn add turbo -W --dev

Exisiting monorepo

yarn add turbo -W --dev

Or

npm install turbo -D

The turbo package is a little shell that will install the proper @turborepo/* packages.

Add turbo to package.json

In your root package.json, add a key turbo. If your git repo's base branch is NOT origin/master then you need to specify a baseBranch too (for example, ours is set to origin/main).

{
  "turbo": {
    "baseBranch": "origin/main"
  }
}

Create a pipeline

In your package.json, add the commands you want to "turbocharge" to your pipeline.

Your pipeline both defines the way in which your NPM package.json scripts relate to each other, and configures cache artifacts for those scripts. These relationships and cache settings are then fanned out and applied to all package tasks across your entire monorepo.

{
  "turbo": {
    "baseBranch": "origin/main",
    "pipeline": {
      "build": {
        "dependsOn": ["^build"],
        "outputs": [".next/**"]
      },
      "test": {
        "dependsOn": ["^build"],
        "outputs": []
      },
      "lint": {
        "outputs": []
      },
      "dev": {
        "cache": false
      }
    }
  }
}

In the above example, the build and test tasks are dependent on their packages dependencies and devDependencies being built first, this is denoted with the ^ prefix.

For each script in each workspace’s package.json, Turborepo will cache files outputted to dist/ and build/ folders by default if an override isn't added. Using the outputs array allows you to override the default cache folders, like in the example above, where the .next/ folder is selected to be the default cache folder for the build task. Turborepo will automatically record and cache logs to .turbo/turbo-<script>.log for you, so you don't ever need to specify that in the outputs array.

Finally, the dev task has its caching disabled using the cache key with a value of false.

See the pipeline documentation for more details on how to configure your pipeline.

Run

To build with your freshly installed turbo, type the following:

yarn turbo run build

Run

Once it’s built, you can run the apps inside your repo:

yarn dev

Summary

Turborepo significantly increases build speeds as well as serves as an abstraction of the declarative build pipeline, easy to use config options, profiling and debugging options and documentation.

Turborepo would most certainly change the minds of people who hesitated the monorepo approach for building apps.