---
title: Overview of the Nx Jest Plugin
description: The Nx Plugin for Jest contains executors and generators that support testing projects using Jest. This page also explains how to configure Jest on your Nx workspace.
---

[Jest](https://jestjs.io/) is an open source test runner created by Facebook. It has a lot of great features:

- Immersive watch mode for providing near instant feedback when developing tests.
- Snapshot testing for validating features.
- Great built-in reporter for printing out test results.

## Setting Up @nx/jest

### Installation

{% callout type="note" title="Keep Nx Package Versions In Sync" %}
Make sure to install the `@nx/jest` version that matches the version of `nx` in your repository. If the version numbers get out of sync, you can encounter some difficult to debug errors. You can [fix Nx version mismatches with this recipe](/recipes/tips-n-tricks/keep-nx-versions-in-sync).
{% /callout %}

In any Nx workspace, you can install `@nx/jest` by running the following command:

{% tabs %}
{% tab label="Nx 18+" %}

```shell {% skipRescope=true %}
nx add @nx/jest
```

This will install the correct version of `@nx/jest`.

{% /tab %}
{% tab label="Nx < 18" %}

Install the `@nx/jest` package with your package manager.

```shell
npm add -D @nx/jest
```

{% /tab %}
{% /tabs %}

#### Configuring @nx/jest/plugin for both E2E and Unit Tests

While Jest is most often used for unit tests, there are cases where it can be used for e2e tests as well as unit tests
within the same workspace. In this case, you can configure the `@nx/jest/plugin` twice for the different cases.

```json {% fileName="nx.json" %}
{
  "plugins": [
    {
      "plugin": "@nx/jest/plugin",
      "exclude": ["e2e/**/*"],
      "options": {
        "targetName": "test"
      }
    },
    {
      "plugin": "@nx/jest/plugin",
      "include": ["e2e/**/*"],
      "options": {
        "targetName": "e2e-local",
        "ciTargetName": "e2e-ci"
      }
    }
  ]
}
```

### Splitting E2E Tests

If Jest is used to run E2E tests, you can enable [splitting the tasks](/ci/features/split-e2e-tasks) by file to get
improved caching, distribution, and retrying flaky tests. Enable this, by providing a `ciTargetName`. This will create a
target with that name which can be used in CI to run the tests for each file in a distributed fashion.

```json {% fileName="nx.json" %}
{
  "plugins": [
    {
      "plugin": "@nx/jest/plugin",
      "include": ["e2e/**/*"],
      "options": {
        "targetName": "e2e-local",
        "ciTargetName": "e2e-ci"
      }
    }
  ]
}
```

### How @nx/jest Infers Tasks

{% callout type="note" title="Inferred Tasks" %}
Since Nx 18, Nx plugins can infer tasks for your projects based on the configuration of different tools. You can read more about it at the [Inferred Tasks concept page](/concepts/inferred-tasks).
{% /callout %}

The `@nx/jest` plugin will create a task for any project that has an Jest configuration file present. Any of the following files will be recognized as an Jest configuration file:

- `jest.config.js`
- `jest.config.ts`
- `jest.config.mjs`
- `jest.config.mts`
- `jest.config.cjs`
- `jest.config.cts`

### View Inferred Tasks

To view inferred tasks for a project, open the [project details view](/concepts/inferred-tasks) in Nx Console or run `nx show project my-project --web` in the command line.

### @nx/jest Configuration

The `@nx/jest/plugin` is configured in the `plugins` array in `nx.json`.

```json {% fileName="nx.json" %}
{
  "plugins": [
    {
      "plugin": "@nx/jest/plugin",
      "options": {
        "targetName": "test"
      }
    }
  ]
}
```

- The `targetName` option controls the name of the inferred Jest tasks. The default name is `test`.

## Using Jest

### Generate a new project set up with Jest

By default, Nx will use Jest when creating applications and libraries.

```shell
nx g @nx/web:app frontend
```

### Add Jest to a project

Run the `configuration` generator

```shell
nx g @nx/jest:configuration --project=<project-name>
```

> Hint: You can use the `--dry-run` flag to see what will be generated.

Replacing `<project-name>` with the name of the project you're wanting to add Jest too.

### Testing Applications

The recommended way to run/debug Jest tests via an editor

- [VSCode](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner)
- [Webstorm](https://blog.jetbrains.com/webstorm/2018/10/testing-with-jest-in-webstorm/)

To run Jest tests via nx use

```shell
nx test frontend
```

### Watching for Changes

Using the `--watch` flag will run the tests whenever a file changes.

```shell
nx test frontend --watch
```

### Snapshot Testing

Jest has support for **Snapshot Testing**, a tool which simplifies validating data. Check out the [official Jest Documentation on Snapshot Testing](https://jestjs.io/docs/en/snapshot-testing).

Example of using snapshots:

```typescript
describe('SuperAwesomeFunction', () => {
  it('should return the correct data shape', () => {
    const actual = superAwesomeFunction();
    expect(actual).toMatchSnapshot();
  });
});
```

When using snapshots, you can update them with the `--updateSnapshot` flag, `-u` for short.

> By default, snapshots will be generated when there are not existing snapshots for the associated test.

```shell
nx test frontend -u
```

Snapshot files should be checked in with your code.

### Performance in CI

Typically, in CI it's recommended to use `nx affected -t test --parallel=[# CPUs] -- --runInBand` for the best performance.

This is because each [jest process creates a workers based on system resources](https://jestjs.io/docs/cli#--maxworkersnumstring), running multiple projects via nx and using jest workers will create too many process overall causing the system to run slower than desired. Using the `--runInBand` flag tells jest to run in a single process.

## Configurations

### Jest

Primary configurations for Jest will be via the `jest.config.ts` file that generated for your project. This file will extend the root `jest.preset.js` file. Learn more about [Jest configurations](https://jestjs.io/docs/configuration#options).

The root level `jest.config.ts` file configures [Jest multi project support](https://jestjs.io/docs/configuration#projects-arraystring--projectconfig).
This configuration allows editor/IDE integrations to pick up individual project's configurations rather than the one at the root.

{% tabs %}
{% tab label="Nx 18+" %}

The set of Jest projects within Nx workspaces tends to change. Instead of statically defining a list in `jest.config.ts`, Nx provides a utility function called `getJestProjectsAsync` which retrieves a list of paths to all the Jest config files from projects using the `@nx/jest:jest` executor or with tasks running the `jest` command.

You can manually add Jest projects not identified by the `getJestProjectsAsync` function by doing something like the following:

```typescript {% fileName="jest.config.ts" %}
import { getJestProjectsAsync } from '@nx/jest';

export default async () => ({
  projects: [
    ...(await getJestProjectsAsync()),
    '<rootDir>/path/to/jest.config.ts',
  ],
});
```

{% /tab %}

{% tab label="Nx < 18" %}

The set of Jest projects within Nx workspaces tends to change. Instead of statically defining a list in `jest.config.ts`, Nx provides a utility function called `getJestProjects` which queries for Jest configurations defined for targets which use the `@nx/jest:jest` executor.

You can add Jest projects which are not included in `getJestProjects()`, because they do not use the Nx Jest executor, by doing something like the following:

```typescript {% fileName="jest.config.ts" %}
import { getJestProjects } from '@nx/jest';

export default {
  projects: [...getJestProjects(), '<rootDir>/path/to/jest.config.ts'],
};
```

{% /tab %}
{% /tabs %}

### Nx

The Nx task options can be configured via the [project config file](/reference/project-configuration) or via the command line flags.

If you're using [inferred tasks](/concepts/inferred-tasks), or running Jest directly with the `nx:run-commands` executor, you can [provide the Jest args](/recipes/running-tasks/pass-args-to-commands) for the command you're running.

If you're using the `@nx/jest:jest` executor, you can provide [the options the executor accepts](/nx-api/jest/executors/jest#options).

### Code Coverage

Enable code coverage with the `--coverage` flag or by adding it to the executor options in the [project configuration file](/reference/project-configuration).

By default, coverage reports will be generated in the `coverage/` directory under projects name. i.e. `coverage/apps/frontend`. Modify this directory with the `--coverageDirectory` flag. Coverage reporters can also be customized with the `--coverageReporters` flag.

> `coverageDirectory` and `coverageReporters` are configurable via the project configuration file as well.

### Global setup/teardown with nx libraries

In order to use Jest's global setup/teardown functions that reference nx libraries, you'll need to register the TS path for jest to resolve the libraries.
Nx provides a helper function that you can import within your setup/teardown file.

```typescript {% fileName="global-setup.ts" %}
import { registerTsProject } from '@nx/js/src/internal';
const cleanupRegisteredPaths = registerTsProject('./tsconfig.base.json');

import { yourFancyFunction } from '@some-org/my-util-library';
export default async function () {
  yourFancyFunction();
}
// make sure to run the clean up!
cleanupRegisteredPaths();
```

If you're using `@swc/jest` and a global setup/teardown file, you have to set the `noInterop: false` and use dynamic imports within the setup function:

```typescript {% fileName="apps/<your-project>/jest.config.ts" %}
/* eslint-disable */
import { readFileSync } from 'fs';

// Reading the SWC compilation config and remove the "exclude"
// for the test files to be compiled by SWC
const { exclude: _, ...swcJestConfig } = JSON.parse(
  readFileSync(`${__dirname}/.swcrc`, 'utf-8')
);

// disable .swcrc look-up by SWC core because we're passing in swcJestConfig ourselves.
// If we do not disable this, SWC Core will read .swcrc and won't transform our test files due to "exclude"
if (swcJestConfig.swcrc === undefined) {
  swcJestConfig.swcrc = false;
}

// jest needs EsModule Interop to find the default exported function
swcJestConfig.module.noInterop = false;

export default {
  globalSetup: '<rootDir>/src/global-setup-swc.ts',
  transform: {
    '^.+\\.[tj]s$': ['@swc/jest', swcJestConfig],
  },
  // other settings
};
```

```typescript {% fileName="global-setup-swc.ts" %}
import { registerTsProject } from '@nx/js/src/internal';
const cleanupRegisteredPaths = registerTsProject('./tsconfig.base.json');

export default async function () {
  // swc will hoist all imports, and we need to make sure the register happens first
  // so we import all nx project alias within the setup function first.
  const { yourFancyFunction } = await import('@some-org/my-util-library');

  yourFancyFunction();

  // make sure to run the clean up!
  cleanupRegisteredPaths();
}
```

## More Documentation

- [Jest Docs](https://jestjs.io/)
