Setup Jest (Ts) for a brand new React project
Manuel Artero Anguita 🟨

Manuel Artero Anguita 🟨 @manuartero

About: Father & happily married 👨‍👩‍👧. Senior Software eng. based on 🇪🇸. TV Apps at @Telefonica. React ⚛️ Professor in a master's program. Js 🟨 Ts 🟦

Location:
Madrid, Spain
Joined:
Jan 18, 2022

Setup Jest (Ts) for a brand new React project

Publish Date: May 27
1 2

Alright, first things first — this post is for me. I’m just promoting a note from my Notion to a post.
Maybe someone finds it useful, who knows 🤷‍♂️.

But don’t get me wrong, the real reason is just to have it handy in case I can’t log into my Notion account.


Context: I'm preparing the resources for my next React course and we're to talk about unit testing (Jest).

We have already npm create vite@latest, and created the well-known <Button />

We want this to work: button.test.tsx

import { render, screen } from "@testing-library/react";
import { Button } from "./button";

describe("<Button />", () => {
  it("renders: match snapshot", () => {
    render(<Button onClick={jest.fn()} />);
    const button = screen.getByRole("button");
    expect(button).toMatchSnapshot();
  });
});
Enter fullscreen mode Exit fullscreen mode

STEPS

npm i --save-dev jest
npm init jest@latest
Enter fullscreen mode Exit fullscreen mode

jest-init

Dependencies (ts)

npm i -D @types/jest
npm i -D @testing-library/react
npm i -D ts-jest
npm i -D jest-environment-jsdom
npm i -D jest-transform-stub
Enter fullscreen mode Exit fullscreen mode

jest.config.mjs

/**
 * For a detailed explanation regarding each configuration property, visit:
 * https://jestjs.io/docs/configuration
 */

/** @type {import('jest').Config} */
const config = {
  clearMocks: true,
  collectCoverage: true,
  collectCoverageFrom: ["src/**"],
  coverageDirectory: "coverage",
  coverageProvider: "v8",
  moduleDirectories: ["node_modules", "src"], // @see https://stackoverflow.com/a/51174924/1614677
  preset: "ts-jest",
  resetMocks: true,
  restoreMocks: true,
  roots: ["<rootDir>/src"],
  testEnvironment: "jsdom",
  testMatch: ["**/?(*.)+(spec|test).[tj]s?(x)"],
  transform: {
    "^.+\\.(js|ts|tsx)$": "ts-jest",
    "^.+.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$":
      "jest-transform-stub",
  },
};

export default config;
Enter fullscreen mode Exit fullscreen mode

Won't work cause of the default tsconfig (2x tsconfigs by default)... this is my tsconfig.json

{
  "compilerOptions": {
    /* type checking */
    "strict": true, // turn on strict mode family
    "noFallthroughCasesInSwitch": true, // every switch case should break or return
    /* modules */
    "baseUrl": "src", // base path for imports
    "module": "ESNext", // ESModules & allows «import.meta»
    "moduleResolution": "Node", // recommended: ts mimic node resolution
    "resolveJsonModule": true, // allows .json files
    /* language */
    "target": "ES2016",
    "jsx": "react-jsx",
    "lib": [
      "DOM",
      "DOM.Iterable",
      "ESNext"
    ],
    /* js support */
    "allowJs": true, // allows .js files
    /* Interop Constraints */
    "esModuleInterop": true, // recommended: compatibility with libraries using CommonJS
    "allowSyntheticDefaultImports": true, // allows «import Foo from 'foo'»
    "forceConsistentCasingInFileNames": true, // checks for case sensitivity file names
    "isolatedModules": true, // force all files to import/export (no global scripts)
    /* completeness */
    "skipLibCheck": true, // skip checking node_modules/*.d.ts files
    /* emit */
    "noEmit": true // checks for errors only
  },
  "include": [
    "src"
  ]
}
Enter fullscreen mode Exit fullscreen mode

==> output

 PASS  src/components/button.test.tsx
  <Button />
    ✓ renders: match snapshot (35 ms)

 › 1 snapshot written.
Enter fullscreen mode Exit fullscreen mode

--
nice.

Comments 2 total

  • JoelBonetR 🥇
    JoelBonetR 🥇May 30, 2025

    Now that you bring this topic up Manuel,

    I'm feeling that a new wave of tools are slowly erasing the older ones out of the dependencies list of new projects, don't you?
    Like I've been using Vitest instead of Jest for some time now, same goes for E2E tests where I'm having playwright rather than the good'Ol cypress or selenium to mention a couple.

    The main reason (besides usually a way easier config) is that the performance is also bumped up in comparison (e.g. Selenium and Cypress use polling loops to wait for elements to appear whereas playwright/puppeteer uses more modern approaches).

    what are your thoughts on that? 🤔

    • Manuel Artero Anguita 🟨
      Manuel Artero Anguita 🟨May 30, 2025

      aaahhhhh the this-is-the-new-ultimate-the-good-one-i-promise-js-framework issue.

      YEP, tools keep getting better; the JS dev experience is light-years ahead of most languages -cough* python you suck cough*-

      As for vitest, IMO it’s mostly a wrapper around jest. I’m sticking with jest for now ... haven’t felt any real improvement there.

      But Playwright? My gosh. It’s a full upgrade over Cypress, Rest in peace Cypress

Add comment