jonsully1.dev

How to Set Up Vitest with Next.js

Cover Image for How to Set Up Vitest with Next.js
Photo byΒ Β  onΒ 
John O'Sullivan
John O'Sullivan
Senior Full Stack Engineer
& DevOps Practitioner

πŸ“– 5 minute read A practical guide to getting Vitest running in your Next.js project.

πŸ§ͺ Why Vitest?

Vitest and React Testing Library are frequently used together for unit testing. Vitest is a blazing-fast test runner built on top of Vite, making it an excellent choice for modern Next.js projects. This guide will walk you through setting up Vitest with Next.js and writing your first tests.

Good to know: Since async Server Components are new to the React ecosystem, Vitest currently does not support them. While you can still run unit tests for synchronous Server and Client Components, we recommend using E2E tests for async components.

⚑ Quickstart

The fastest way to get started is using create-next-app with the Next.js with-vitest example:

npx create-next-app --example with-vitest with-vitest-app

This scaffolds a fully configured Next.js project with Vitest ready to go out of the box.

πŸ”§ Manual Setup

If you'd prefer to add Vitest to an existing project, install vitest and the following packages as dev dependencies:

Using TypeScript

npm install -D vitest @vitejs/plugin-react jsdom @testing-library/react @testing-library/dom vite-tsconfig-paths

Using JavaScript

npm install -D vitest @vitejs/plugin-react jsdom @testing-library/react @testing-library/dom

Configure Vitest

Create a vitest.config.mts file in the root of your project with the following options:

// vitest.config.mts
import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react'
import tsconfigPaths from 'vite-tsconfig-paths'

export default defineConfig({
  plugins: [tsconfigPaths(), react()],
  test: {
    environment: 'jsdom',
  },
})

Here's what each part does:

  • tsconfigPaths() β€” Resolves path aliases from your tsconfig.json, so imports like @/components/Button work seamlessly in tests.
  • react() β€” Enables JSX/TSX transformation so your React components can be rendered in tests.
  • environment: 'jsdom' β€” Simulates a browser-like DOM environment for testing UI components.

For more information on configuring Vitest, refer to the Vitest Configuration docs.

Add a Test Script

Add a test script to your package.json:

{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "test": "vitest"
  }
}

When you run npm run test, Vitest will watch for changes in your project by default β€” re-running relevant tests automatically as you edit your code.

βœ… Creating Your First Vitest Unit Test

Let's verify everything is working by creating a test that checks whether a <Page /> component successfully renders a heading.

The Component

// pages/index.tsx
import Link from 'next/link'

export default function Page() {
  return (
    <div>
      <h1>Home</h1>
      <Link href="/about">About</Link>
    </div>
  )
}

The Test

// __tests__/index.test.tsx
import { expect, test } from 'vitest'
import { render, screen } from '@testing-library/react'
import Page from '../pages/index'

test('Page', () => {
  render(<Page />)
  expect(
    screen.getByRole('heading', { level: 1, name: 'Home' })
  ).toBeDefined()
})

This test:

  1. Renders the <Page /> component into a virtual DOM using React Testing Library.
  2. Queries for an <h1> element with the text "Home".
  3. Asserts that the element exists β€” if it doesn't, the test fails.

πŸƒ Running Your Tests

Run your tests with:

npm test

You should see Vitest pick up the test file and report a passing result. From here, you can expand your test suite to cover more components, hooks, and utility functions.

πŸ“š Additional Resources