# Run only the test at line 42
Source: https://speakeasy.com/blog/vitest-vs-jest

import { Callout, Table } from "@/mdx/components";


<Callout title="NOTE" type="info">
This article was updated in January 2025 to reflect the release of [Vitest 3](https://github.com/vitest-dev/vitest/releases/tag/v3.0.0), which introduces new features and improvements, as well as some breaking changes. Be sure to check the [official Vitest documentation](https://vitest.dev/blog/vitest-3.html) and migration guide for further details.
</Callout>

Effective testing frameworks are essential in building reliable JavaScript applications, helping you minimize bugs and catch them early to keep your customers happy. Choosing the right testing framework saves hours of configuration hassles and improves developer experience.

This post compares [Jest](https://jestjs.io/) and [Vitest](https://vitest.dev/), popular JavaScript testing frameworks that support unit testing, integration testing, and [snapshot testing](https://jestjs.io/docs/snapshot-testing).

**Jest** — created by the Facebook team, is the most widely used JavaScript testing framework.

**Vitest** — a fast-growing new testing framework. Originally built for [Vite](https://vite.dev/), the popular development server and JavaScript bundler, Vitest can now be used with any JavaScript project, not just those using Vite.

## Which JavaScript testing framework is right for you?

We think Vitest is best, unless you're using a framework or library that has better Jest support, such as React Native. The table below compares some features of the two testing frameworks. **If you're starting a new project, use Vitest**. With ES module, TypeScript, JSX, and PostCSS support out of the box, Vitest is the right choice for almost every modern JavaScript app. 

<Table
  title="Feature comparison"
  columns={[
    { key: "feature", header: "Feature" },
    { key: "jest", header: "Jest" },
    { key: "vitest", header: "Vitest" }
  ]}
  data={[
    { feature: "Battle tested by large companies", jest: "✅", vitest: "❌" },
    { feature: "ES module support", jest: "✅*", vitest: "✅" },
    { feature: "TypeScript support", jest: "✅+", vitest: "✅" },
    { feature: "Browser UI", jest: "❌", vitest: "✅*" },
    { feature: "Type testing", jest: "❌", vitest: "✅*" },
    { feature: "Benchmarking", jest: "❌", vitest: "✅" },
    { feature: "In-source testing", jest: "❌", vitest: "✅" },
    { feature: "Browser mode", jest: "❌", vitest: "✅*" },
    { feature: "Multi-browser support", jest: "❌", vitest: "✅" },
    { feature: "Enhanced error matching", jest: "❌", vitest: "✅" },
    { feature: "Project-level configuration", jest: "✅", vitest: "✅**" },
    { feature: "Snapshot testing", jest: "✅", vitest: "✅" },
    { feature: "Interactive snapshot testing", jest: "✅", vitest: "❌" },
    { feature: "Code coverage", jest: "✅", vitest: "✅" },
    { feature: "Concurrent testing", jest: "✅*", vitest: "✅" },
    { feature: "Sharding support", jest: "✅", vitest: "✅" },
    { feature: "Multi-project runner", jest: "✅", vitest: "❌" },
    { feature: "Mocking", jest: "✅", vitest: "✅" }
  ]}
  rowKeyField="feature"
/>

\* Experimental <br/>
\+ Using Babel <br/>
\*\* Includes inline workspace support


At Speakeasy, we've tried both Jest and Vitest, and ultimately chose Vitest – even without Vite in our setup.

We decided to document our experience and dive deeper into both Vitest and Jest, comparing the two testing frameworks in terms of their features, performance, and developer experience to further help you decide which is best for your use case. We'll also share our experience of migrating from Jest to Vitest for our TypeScript SDK and how we're using Vitest for our new automated API testing feature, which is currently in beta, for Speakeasy-created SDKs.

## Jest's beginnings: From Facebook to open source

Back in 2011, no JavaScript testing framework existed that met the Facebook (now Meta) team's testing needs, so they built Jest. Jest was open-sourced in 2014, shortly after React was open-sourced, and as React rapidly gained in popularity, so did Jest.

Popular React project starter [Create React App](https://create-react-app.dev/) integrated Jest as its default testing framework in 2016 and Jest soon became the go-to testing tool for React developers. When Next.js, the most popular React framework, included built-in Jest configuration in version 12, Jest's dominance in the React ecosystem was secured.

Ownership of Jest was transferred to the [OpenJS Foundation](https://engineering.fb.com/2022/05/11/open-source/jest-openjs-foundation/) in 2022 and the framework is currently maintained by a core group of contributors external to Meta.

## Jest features

Jest's popularity is in part thanks to the extensive Jest API that handles a variety of testing needs, including snapshots, mocking, and code coverage, making it suitable for most unit testing situations. Jest works with Node.js and frontend frameworks like React, Angular, and Vue, and can be used with TypeScript using Babel or the `ts-jest` library to transpile TypeScript to JavaScript.

Consider the following example snapshot test:

```javascript filename="link.test.js.snap"
test("Checkout link renders correctly", () => {
  const tree = renderer
    .create(<Link page="http://www.instagram.com">Go to checkout</Link>)
    .toJSON();
  expect(tree).toMatchSnapshot();
});
```

The [`test`](https://jestjs.io/docs/api#testname-fn-timeout) method runs a test. The Jest [`expect` API](https://jestjs.io/docs/expect) provides modifier and matcher (assertion) methods that simplify checking whether a value is what you expect it to be. Among the matcher methods available are:

- `toBe()`
- `toHaveProperty()`
- `toMatchSnapshot()`

Jest's extensive set of modifiers and matchers makes error messages more detailed, helping you pinpoint why a test fails. The [jest-extended](https://github.com/jest-community/jest-extended) library, maintained by the Jest community, provides additional matchers to expand testing functionality.

You can use Jest's [mock functions](https://jestjs.io/docs/mock-functions) to mock objects, function calls, and even npm modules for faster testing without relying on external systems. This is especially useful for avoiding expensive function calls like calling a credit card charging API in the checkout process of an app.

To run code before and after tests run, Jest provides handy [setup and teardown functions](https://jestjs.io/docs/setup-teardown): `beforeEach`, `afterEach`, `beforeAll`, and `afterAll`.

```javascript filename="cityDb.test.js"
beforeAll(() => {
  return initializeCityDatabase();
});

afterAll(() => {
  return clearCityDatabase();
});
```

```javascript filename="cityDb.test.js"
beforeEach(() => {
  initializeCityDatabase();
});

afterEach(() => {
  clearCityDatabase();
});

test("city database has Vienna", () => {
  expect(isCity("Vienna")).toBeTruthy();
});

test("city database has San Juan", () => {
  expect(isCity("San Juan")).toBeTruthy();
});
```

When running tests, you can add the `--watch` flag to only run tests related to changed files.

```shell
jest --watch
```

While Vitest doesn't have Jest's [Interactive Snapshot Mode](https://jestjs.io/docs/snapshot-testing#interactive-snapshot-mode), which enables you to update failed snapshots interactively in watch mode, this feature has been [added to Vitest's TODO list](https://github.com/vitest-dev/vitest/issues/2229).

Jest also has a multi-project runner for running tests across multiple projects, each with their own setup and configuration, using a single instance of Jest.

## Getting started with Jest

To set up a basic test, install Jest as a development dependency:

```shell
npm install --save-dev jest
```

Create a test file with `.test` in its name, for example, `sum.test.js`:

```javascript filename="sum.test.js"  
const sum = require("./sum");

test("adds 1 + 2 to equal 3", () => {
  expect(sum(1, 2)).toBe(3);
});
```

This code imports a `sum` function that adds two numbers and then checks that `1` and `2` have been correctly added.

Add the following script to your `package.json` file:

```json filename="package.json"
{
  "scripts": {
    "test": "jest"
  }
}
```

Run the test using the following command:

```shell
npm run test
```

Jest finds the test files and runs them. Jest will print the following message in your terminal if the test passes:

```shell
PASS  ./sum.test.js
✓ adds 1 + 2 to equal 3 (5ms)
```

## The origin of Vitest: The need for a Vite-native test runner

The introduction of in-browser ES modules support led to the creation of the popular JavaScript bundler and development server Vite, which uses ES modules to simplify and speed up bundling during development. While it's possible to use Jest with Vite, this approach creates separate pipelines for testing and development. Among other factors, Jest requires separate configuration to transpile ES modules to CommonJS using Babel. A test runner that supports ES modules would integrate better with Vite and simplify testing. Enter Vitest.

Developed by core Vite team member, Anthony Fu, Vitest is built on top of Vite, but you can use it in projects that don't use Vite.

Vite's rise in popularity can be attributed to its simplicity and performance. Unlike traditional JavaScript bundlers that can be slow when running development servers for large projects, the Vite development server loads fast, as no bundling is required. Instead, Vite transforms and serves source code as ES modules to the browser on demand, functionality that allows for fast Hot Module Replacement (HMR) - the updating of modules while an app is running without a full reload - even for large applications.

In development, the main advantages of using Vitest with Vite are their performance during development, ease of integration, and shared configuration. Vitest's growing adoption is partly driven by the widespread success of Vite.

## Vitest features

Vitest has built-in ES module, TypeScript, JSX, and PostCSS support and many of the same features as Jest, like the `expect` API, snapshots, and code coverage. Vitest's Jest-compatible API makes migrating from Jest easy. Take a look at the differences between the frameworks in the [migrating from Jest guide](https://vitest.dev/guide/migration.html#migrating-from-jest) in the Vitest docs.

With Vitest 3, several features have been enhanced. The code coverage functionality now automatically excludes test files by default, providing cleaner coverage reports. The mocking capabilities have also been expanded, with the new version including spy reuse for already mocked methods, reducing test boilerplate, and adding powerful new matchers like `toHaveBeenCalledExactlyOnceWith`:

```javascript
test('vitest mocking example', () => {
  const mock = vi.fn();
  mock('hello');
  // New matcher for more precise assertions
  expect(mock).toHaveBeenCalledExactlyOnceWith('hello');
  
  // Spy reuse example
  const obj = {
    method: () => {}
  };
  const spy = vi.spyOn(obj, 'method');
  // Spy is automatically reused if spyOn is called again
  const sameSpy = vi.spyOn(obj, 'method');
  expect(spy === sameSpy).toBe(true);
});
```

In contrast to Jest, Vitest uses watch mode by default for a better developer experience. Vitest searches the ES module graph and only reruns affected tests when you modify your source code, similar to how Vite's HMR works in the browser. This makes test reruns fast - so fast that Vitest adds a delay before displaying test results in the terminal so that developers can see that the tests were rerun.

Vitest supports [Happy DOM](https://github.com/capricorn86/happy-dom) and [jsdom](https://github.com/jsdom/jsdom) for DOM mocking. While Happy DOM is more performant than jsdom, which is used by Jest, jsdom is a more mature package with a more extensive API that closely emulates the browser environment.

When running tests, Vitest runs a Vite dev server that provides a UI for managing your tests. Vitest 3 significantly improves the UI experience with several new features:

- Run individual tests or test suites right from the UI for easier debugging.
- Quickly spot and fix issues with automatic scrolling to failed tests.
- Get a clearer view of your test dependencies with toggleable `node_modules` visibility.
- Better organize your tests with improved filtering, search, and management controls.

To view the UI, install `@vitest/ui` and pass the `--ui` flag to the Vitest run command:

```shell
vitest --ui
```

![Vitest UI](/assets/blog/vitest-vs-jest/vitest-ui.png)

Take a look at the StackBlitz [Vitest Basic Example](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/basic?initialPath=__vitest__/) for a live demo of the Vitest UI. At Speakeasy, we've found Vitest's UI to be a valuable tool for debugging. 

Vitest also has Rust-like [in-source testing](https://vitest.dev/guide/in-source) that lets you run tests in your source code:

```javascript filename="add.ts"
export function add(...args: number[]) {
  return args.reduce((a, b) => a + b, 0)
}

// in-source test suites
if (import.meta.vitest) {
  const { it, expect } = import.meta.vitest
  it('add', () => {
    expect(add()).toBe(0)
    expect(add(1)).toBe(1)
    expect(add(1, 2, 3)).toBe(6)
  })
}
```

While using separate test files is recommended for more complex tests, in-source testing is suitable for unit testing small functions and prototyping, making it especially useful for writing tests for JavaScript libraries.

Vitest's recent experimental [browser mode](https://vitest.dev/guide/browser/) feature allows you to run tests in the browser, instead of simulating them in Node.js. [WebdriverIO](https://webdriver.io/) is used for running tests, but you can use other providers. You can also browse in headless mode using WebdriverIO or [Playwright](https://playwright.dev/). Vitest developed browser mode to improve test accuracy by using a real browser environment and streamline test workflows, but you may find browser mode slower than using a simulated environment as it needs to launch a browser, handle page rendering, and interact with browser APIs.

Vitest 3 introduces powerful new CLI features that upgrade test execution flexibility. You can now exclude specific projects using patterns with `--project=!pattern`, making it easier to manage test runs in monorepos or large projects. The new line-number-based test filtering allows you to run specific tests by their location in the file:

```shell

vitest path/to/test.ts:42