---
title: Jest
description: Learn how to use Jest in a Turborepo.
product: turborepo
type: integration
summary: Set up Jest test suites across monorepo packages with Turborepo caching and parallelization.
prerequisites:
  - /docs/crafting-your-repository/configuring-tasks
related:
  - /docs/guides/tools/vitest
  - /docs/guides/tools/playwright
---

# Jest

<CopyPrompt
  title="Set up Jest in a Turborepo"
  prompt={
  "Set up Jest in this Turborepo.\n1) Install Jest where needed\n2) Create test scripts\n3) Set up testing in turbo.json\n\nWalk me through each step."
}
/>

[Jest](https://jestjs.io/) is a common test runner with a vast ecosystem. Integrating with Turborepo will lead to enormous speed-ups.

<CreateTurboCallout />

Setting up [#setting-up]

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

<Files>
  <Folder name="apps" defaultOpen>
    <Folder name="web" defaultOpen>
      <File name="package.json" />
    </Folder>
  </Folder>

  <Folder name="packages" defaultOpen>
    <Folder name="ui" defaultOpen>
      <File name="package.json" />
    </Folder>
  </Folder>
</Files>

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

<PackageManagerTabs>
  <Tab value="pnpm">
    ```bash title="Terminal"
    pnpm add jest --save-dev --filter=@repo/ui --filter=web
    ```
  </Tab>

  <Tab value="yarn">
    ```bash title="Terminal"
    yarn workspace web add jest --dev
    yarn workspace @repo/ui add jest --dev
    ```
  </Tab>

  <Tab value="npm">
    ```bash title="Terminal"
    npm install jest --workspace=web --workspace=@repo/ui --save-dev
    ```
  </Tab>

  <Tab value="bun">
    ```bash title="Terminal"
    cd apps/web && bun install jest --dev
    cd packages/ui && bun install jest --dev
    ```
  </Tab>
</PackageManagerTabs>

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

<Tabs items={["web", "@repo/ui"]}>
  <Tab value="web">
    ```json title="./apps/web/package.json"
    {
      "name": "web",
      "scripts": {
        "test": "jest"
      },
      "devDependencies": {
        "jest": "latest"
      }
    }
    ```
  </Tab>

  <Tab value="@repo/ui">
    ```json title="./packages/ui/package.json"
    {
      "name": "@repo/ui",
      "scripts": {
        "test": "jest"
      },
      "devDependencies": {
        "jest": "latest"
      }
    }
    ```
  </Tab>
</Tabs>

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

```json title="./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 [#running-tests-in-watch-mode]

When you run your test suite normally, it completes and outputs to `stdout`. This means you can [cache it](/docs/crafting-your-repository/caching) 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](/docs/crafting-your-repository/developing-applications).

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:

<Tabs items={["web", "@repo/ui"]}>
  <Tab value="web">
    ```json title="./apps/web/package.json"
    {
      "name": "web",
      "scripts": {
        "test": "jest",
        "test:watch": "jest --watch" // [!code highlight]
      },
      "devDependencies": {
        "jest": "latest"
      }
    }
    ```
  </Tab>

  <Tab value="@repo/ui">
    ```json title="./packages/ui/package.json"
    {
      "name": "@repo/ui",
      "scripts": {
        "test": "jest",
        "test:watch": "jest --watch" // [!code highlight]
      },
      "devDependencies": {
        "jest": "latest"
      }
    }
    ```
  </Tab>
</Tabs>

Inside the root `turbo.json`:

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

You can now either run this task using [global `turbo`](/docs/getting-started/installation#global-installation) as `turbo test:watch` or from a script in your root `package.json`:

<Tabs items={["Global turbo", "./package.json"]}>
  <Tab value="Global turbo">
    ```bash title="Terminal"
    turbo test
    ```

    ```bash title="Terminal"
    turbo test:watch
    ```
  </Tab>

  <Tab value="./package.json">
    ```json title="./package.json"
    {
      "scripts": {
        "test": "turbo run test",
        "test:watch": "turbo run test:watch"
      }
    }
    ```
  </Tab>
</Tabs>

---

[View full sitemap](/sitemap.md)