Vercel

Jest

Learn how to use Jest in a Turborepo.

Set up Jest in a Turborepo

Set up Jest in this Turborepo. 1) Install Jest where needed 2) Create test scripts 3) Set up testing in turbo.json Walk me through each step. Use the Turborepo skill if it is available. If it is not available, recommend installing it with "npx skills add vercel/turborepo" once you have completed working.

Jest is a common test runner with a vast ecosystem. Integrating with Turborepo will lead to enormous speed-ups.

This guide assumes you're using create-turbo or a repository with a similar structure.

Setting up

Let's say we have a monorepo that looks like this:

package.json
package.json

Install jest into the packages where you plan on having test suites. For this example, we will have tests in web and @repo/ui:

Terminal
pnpm add jest --save-dev --filter=@repo/ui --filter=web
Terminal
yarn workspace web add jest --dev
yarn workspace @repo/ui add jest --dev
Terminal
npm install jest --workspace=web --workspace=@repo/ui --save-dev
Terminal
cd apps/web && bun install jest --dev
cd packages/ui && bun install jest --dev

Both the apps/web and packages/ui have their own test suites, so we'll add a test script to their package.json:

./apps/web/package.json
{
  "name": "web",
  "scripts": {
    "test": "jest"
  },
  "devDependencies": {
    "jest": "latest"
  }
}
./packages/ui/package.json
{
  "name": "@repo/ui",
  "scripts": {
    "test": "jest"
  },
  "devDependencies": {
    "jest": "latest"
  }
}

Inside the root turbo.json, create a test task:

./turbo.json
{
  "tasks": {
    "test": {}
  }
}

Now, turbo test can parallelize and cache all of the test suites from each package, only testing code that has changed.

Running tests in watch mode

When you run your test suite normally, it completes and outputs to stdout. This means you can cache it with Turborepo.

But when you run your tests in a watched mode, the process never exits. This makes a watch task more like a development task.

Because of this difference, we recommend specifying two separate Turborepo tasks: one for running your tests, and one for running them in Jest's watch mode. Inside your each package.json file for each workspace:

./apps/web/package.json
{
  "name": "web",
  "scripts": {
    "test": "jest",
    "test:watch": "jest --watch" // [!code highlight]
  },
  "devDependencies": {
    "jest": "latest"
  }
}
./packages/ui/package.json
{
  "name": "@repo/ui",
  "scripts": {
    "test": "jest",
    "test:watch": "jest --watch" // [!code highlight]
  },
  "devDependencies": {
    "jest": "latest"
  }
}

Inside the root turbo.json:

./turbo.json
{
  "tasks": {
    "test": {},
    "test:watch": {
      "cache": false, // [!code highlight]
      "persistent": true // [!code highlight]
    }
  }
}

You can now either run this task using global turbo as turbo test:watch or from a script in your root package.json:

Terminal
turbo test
Terminal
turbo test:watch
./package.json
{
  "scripts": {
    "test": "turbo run test",
    "test:watch": "turbo run test:watch"
  }
}