In the previous article, we set up a monorepo project with 2 applications and a package. We also enabled Yarn workspaces to manage the dependencies and linking of the workspaces.

One inconvenience so far was having to start 2 separate terminal windows to run the applications. This isn’t a huge issue at the moment, but it doesn’t scale well. Let’s introduce Turborepo to handle this; it also adds some extra benefits I’ll talk about later in this article.

1. Start the monorepo with just 1 command

Install Turborepo as a root devDependency.

yarn add turbo -D -W

And add .turbo to our ‘.gitignore’ file.

.gitignore

...
.turbo

Let’s start with the ‘dev‘ script. Add a dev script in our root ‘package.json’ that uses Turborepo to run all workspace dev scripts.

package.json

"scripts": {
    "dev": "turbo run dev",
},

Run ‘yarn dev‘ in the root of your project, you’ll get the following error.

Could not find turbo.json. Follow directions at https://turborepo.org/docs/getting-started to create one

Let’s create a configuration file (called ‘turbo.json’) containing an empty object for now.

turbo.json

{ }

Run ‘yarn dev‘, again.

task `dev` not found in turbo pipeline in package.json. Are you sure you added it?

We’re making progress. Turborepo is looking for a dev pipeline, one that is currently not defined in our configuration file. Let’s create a minimal configuration file.

turbo.json

{
  "$schema": "https://turborepo.org/schema.json",
  "baseBranch": "origin/main",
  "pipeline": {
    "dev": {}
  }
}

We’re defining a pipeline called ‘dev’ which currently has no additional configuration. We’re also providing a link to the schema (for better IDE integration) and provide a baseBranch.

Run ‘yarn dev‘, again.

This time, Turborepo runs all dev scripts in the workspaces defined in ‘package.json’. If a workspace has no ‘dev’ script, it is ignored.

There is a warning, though, which is easy to fix.

Did not find "packageManager" in your package.json. Please run "npx @turbo/codemod add-package-manager"

Run the suggested command to fill in the ‘packageManager‘ key in your root ‘package.json’. Commit or stash your changes before doing so or run it with the –force flag. This key will help Turborepo identify the package manager you’re currently using.

2. Run scripts for one application in a monorepo

Sometimes, you only want to run scripts in a specific workspace. Define the scope using the flag. Here, ‘admin’ is the name of the application (package.json name property) you want to target.

yarn dev --scope=admin

Let’s add an extra build script. Add build scripts in the ‘package.json’ file of each application (‘admin’ & ‘client’).

apps/client/package.json

"build": "next build -p 3000"

Do the same for the admin application (apps/admin/package.json); make sure you define a different port (3001).

Add a build script in the root ‘package.json’

package.json

"build": "turbo run build"

Define a pipeline in our configuration file. Since the build script is only dependent on its own dependencies, we define the dependsOn as ‘^build’. Since Next.js outputs a ‘.next’ folder when creating a build, make sure you mark it as the output of the ‘build’ pipeline.

turbo.json

"build": {
  "dependsOn": ["^build"],
  "outputs": [".next/**"]
}

Trigger the build process by running ‘yarn build‘. Wait for it to finish. Now run it again. Something interesting happened.

Since we didn’t make any changes between the previous and the current build, Turborepo replays the cache and goes into “FULL TURBO” mode, saving you some precious time. We will make use of this mechanism (through remote caching) in our deployment flow later.

3. Configure Turborepo cache settings

For some pipelines, we can disable caching. There is no need to cache our dev output, let’s disable it.

turbo.json

"dev": { "cache": false }

Now we have two scripts, one that runs our applications in development mode and another that builds our applications.

With this knowledge, try to set up a ‘start’ pipeline. ‘next start‘ runs the production build process for a single Next.js project, so we need to make sure it is built first.

Make sure you:

  • add the correct scripts to the applications
  • create a script in the root ‘package.json’
  • edit ‘turbo.json’ (what should ‘dependsOn’ contain?)

One final thing we can enable is remote caching. This will make it possible to share the Turborepo cache between several developers. This is a beta feature that is currently supported by Vercel.

Login to Vercel using ‘npx turbo login‘ and link your cache via ‘npx turbo link‘.

Let’s verify if this works; run a build (‘yarn build‘). You should spot ‘Remote computation caching enabled (experimental)‘ in the log.

Remove your local cache by running

rm -rf ./node_modules/.cache/turbo

And run your build again. Now it should use the remote cache. You can also set up your own caching server (more information here).

That’s it for now. You’ve successfully configured your scripts in a monorepo. In the next article, I’ll show you how we deploy the applications in our monorepo to Vercel using our current scripts whilst leveraging the remote cache.

Here are some party balloons to celebrate.

balloons monorepos