Agent skill

Vitest

by jezweb in jezweb/claude-skills

Set up Vitest testing in any project — detects type (Cloudflare Workers, React, Node, library), generates vitest.config.ts, test setup, utilities, and a sample test.

MITAuto-check passedTesting & QA

Install Vitest

skills CLI
$ npx skills add jezweb/claude-skills --skill vitest -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install jezweb/claude-skills vitest --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/jezweb/claude-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/plugins/dev-tools/skills/vitest .claude/skills/vitest && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
vitest
GitHub stars
1.1k
Token cost
~3k tokens
SKILL.md length
645 words
Files
1
Skills in repo
52
Repo updated
First seen
Licence
MIT

At a glance

Set up Vitest testing in any project — detects type (Cloudflare Workers, React, Node, library), generates vitest.config.ts, test setup, utilities, and a sample test.

  • Works in 8 steps: Detect Project Type → Install Dependencies → Generate vitest.config.ts → …
  • The user mentions adding tests
  • SKILL.md covers Workflow, Step 1: Detect Project Type, Step 2: Install Dependencies and Step 3: Generate…, plus 9 more sections
  • Calls pnpm

What it does

Vitest is an agent skill from jezweb/claude-skills. Set up Vitest testing in any project — detects type (Cloudflare Workers, React, Node, library), generates vitest.config.ts, test setup, utilities, and a sample test. Covers mocking patterns, coverage config, workspace setup, Jest migration. Use whenever the user mentions adding tests, setting up Vitest, configuring tests, migrating from Jest, fixing testing infrastructure, or asks 'how do I test this'.

Its SKILL.md is about 3k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Testing & QA, covering Unit testing. It works with Vitest, React, Cloudflare Workers and Jest. The repository describes itself as: Skills for Claude Code CLI such as full stack dev Cloudflare, React, Tailwind v4, and AI integrations. The licence is MIT.

When your agent uses it

  • The user mentions adding tests
  • Setting up Vitest
  • Configuring tests
  • Migrating from Jest

Example prompts

  • “how do I test this”
  • “/vitest”

Workflow steps

8 steps, taken from the step headings in SKILL.md.

  1. Detect Project Type
  2. Install Dependencies
  3. Generate vitest.config.ts
  4. Generate Test Setup File
  5. Add TypeScript Config
  6. Add Package.json Scripts
  7. Generate Sample Test
  8. Verify

What it can do on your machine

Read from SKILL.md and the folder at commit 64965d9. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • pnpm

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use pnpm, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Vitest loads about 3k tokens when it runs. Until then it costs about 103 tokens; SKILL.md has 645 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~103
When it runs · the whole SKILL.md, loaded when a task matches
~3k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from jezweb/claude-skills at commit 64965d9, republished under its MIT licence (© jezweb). 645 words, ~3,001 tokens.

Download SKILL.mdSave it as .claude/skills/vitest/SKILL.md (or your agent's skills folder).
name
vitest
description
Set up Vitest testing in any project — detects type (Cloudflare Workers, React, Node, library), generates vitest.config.ts, test setup, utilities, and a sample test. Covers mocking patterns, coverage config, workspace setup, Jest migration. Use whenever the user mentions adding tests, setting up Vitest, configuring tests, migrating from Jest, fixing testing infrastructure, or asks 'how do I test this'.
license
MIT

Vitest Setup

Detect the project type, generate the right Vitest configuration, and produce working test infrastructure. Not a reference card — this skill creates files.

Workflow

  1. Detect — scan the project to determine type and existing setup
  2. Configure — generate vitest.config.ts tailored to the environment
  3. Scaffold — create test setup, utilities, and a sample test
  4. Wire up — add package.json scripts and TypeScript config

Step 1: Detect Project Type

Read these files to determine the project:

package.json          → dependencies, scripts, type field
tsconfig.json         → paths, compiler options
wrangler.toml         → Cloudflare Workers project
vite.config.ts        → existing Vite setup (extend, don't replace)
vitest.config.ts      → already configured? just fill gaps
jest.config.*         → migration candidate
src/                  → source structure

Classify as one of:

TypeSignalsEnvironment
Cloudflare Workerswrangler.toml, @cloudflare/workers-types, cloudflare vite pluginnode with Workers-specific setup
React (Vite)@vitejs/plugin-react, react-domjsdom or happy-dom
React (SSR/TanStack Start)@tanstack/start, vinxiSplit: node for server, jsdom for client
Node/Hono APIhono, express, no react-domnode
Libraryexports field, no framework depsnode

If a vite.config.ts already exists, extend it rather than creating a separate vitest.config.ts — Vitest reads Vite config natively.

Step 2: Install Dependencies

Generate the install command based on detected type:

bash
# Base (always)
pnpm add -D vitest

# React projects — add jsdom and Testing Library
pnpm add -D @vitest/coverage-v8 jsdom @testing-library/react @testing-library/jest-dom @testing-library/user-event

# Workers projects — add Cloudflare test utilities
pnpm add -D @vitest/coverage-v8 @cloudflare/vitest-pool-workers

# Node/Hono projects
pnpm add -D @vitest/coverage-v8

# If migrating from Jest, also remove:
pnpm remove jest ts-jest @types/jest jest-environment-jsdom babel-jest

Use the project's package manager (check for pnpm-lock.yaml, yarn.lock, bun.lockb, or package-lock.json).

Step 3: Generate vitest.config.ts

Cloudflare Workers
typescript
import { defineWorkersConfig } from "@cloudflare/vitest-pool-workers/config";

export default defineWorkersConfig({
  test: {
    globals: true,
    poolOptions: {
      workers: {
        wrangler: { configPath: "./wrangler.toml" },
      },
    },
  },
});

If the project uses the Cloudflare Vite plugin (@cloudflare/vite-plugin), integrate into the existing vite.config.ts instead:

typescript
/// <reference types="vitest/config" />
import { defineConfig } from "vite";
import { cloudflare } from "@cloudflare/vite-plugin";

export default defineConfig({
  plugins: [cloudflare()],
  test: {
    globals: true,
  },
});
React (Vite)
typescript
/// <reference types="vitest/config" />
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
  test: {
    globals: true,
    environment: "jsdom",
    setupFiles: ["./src/test/setup.ts"],
    css: true,
  },
});

If a vite.config.ts already exists, add the test block to it rather than creating a new file.

Node / Hono API
typescript
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    globals: true,
    environment: "node",
  },
});
With Coverage (add to any config)
typescript
  test: {
    // ... existing config
    coverage: {
      provider: "v8",
      reporter: ["text", "html", "lcov"],
      exclude: [
        "node_modules/",
        "**/*.config.*",
        "**/*.d.ts",
        "**/test/**",
      ],
    },
  },

Step 4: Generate Test Setup File

Create src/test/setup.ts (React projects only):

typescript
import "@testing-library/jest-dom/vitest";

That single import adds all the custom matchers (toBeInTheDocument, toHaveTextContent, etc.) and registers the Vitest expect.extend automatically.

Step 5: Add TypeScript Config

Add to tsconfig.json compilerOptions:

json
{
  "compilerOptions": {
    "types": ["vitest/globals"]
  }
}

For projects with multiple tsconfig files (e.g. tsconfig.app.json + tsconfig.node.json), add to the one that covers test files — usually the root tsconfig.json or create a tsconfig.test.json that extends it.

Step 6: Add Package.json Scripts

json
{
  "scripts": {
    "test": "vitest",
    "test:run": "vitest run",
    "test:coverage": "vitest run --coverage",
    "test:ui": "vitest --ui"
  }
}

Don't overwrite existing scripts — merge with what's there.

Step 7: Generate Sample Test

Write one test file that demonstrates the right patterns for this specific project. Place it next to real source code, not in a separate __tests__ directory.

For a Hono API route (e.g. src/routes/health.ts):
typescript
import { describe, it, expect } from "vitest";
import { app } from "../index";

describe("GET /health", () => {
  it("returns 200 with status ok", async () => {
    const res = await app.request("/health");
    expect(res.status).toBe(200);

    const body = await res.json();
    expect(body).toEqual({ status: "ok" });
  });
});
For a React component (e.g. src/components/Button.tsx):
typescript
import { describe, it, expect } from "vitest";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { Button } from "./Button";

describe("Button", () => {
  it("renders with label", () => {
    render(<Button>Click me</Button>);
    expect(screen.getByRole("button", { name: /click me/i })).toBeInTheDocument();
  });

  it("calls onClick when clicked", async () => {
    const user = userEvent.setup();
    const handleClick = vi.fn();
    render(<Button onClick={handleClick}>Click me</Button>);

    await user.click(screen.getByRole("button"));
    expect(handleClick).toHaveBeenCalledOnce();
  });
});
For a utility function (e.g. src/utils/format.ts):
typescript
import { describe, it, expect } from "vitest";
import { formatCurrency } from "./format";

describe("formatCurrency", () => {
  it("formats whole numbers", () => {
    expect(formatCurrency(1000)).toBe("$1,000.00");
  });

  it("formats decimals", () => {
    expect(formatCurrency(49.9)).toBe("$49.90");
  });

  it("handles zero", () => {
    expect(formatCurrency(0)).toBe("$0.00");
  });
});

Pick a real file from the project to test. Don't invent a fake module — the sample test should run immediately after setup.

Show full SKILL.md (278 more words)Show less

Step 8: Verify

Run the tests to confirm everything works:

bash
pnpm test:run

If it fails, diagnose and fix. Common issues:

ErrorFix
Cannot find module 'vitest'Check install completed, check node_modules/.vitest exists
ReferenceError: describe is not definedAdd globals: true to config, or add types: ["vitest/globals"] to tsconfig
document is not definedWrong environment — set environment: "jsdom" for React tests
Cannot use import.metaEnsure vitest.config uses .ts extension and project has "type": "module" or Vite handles transforms
Workers bindings undefinedUse @cloudflare/vitest-pool-workers instead of plain vitest, check wrangler.toml path

Mocking Reference

These patterns are for writing tests after setup is complete. Include them in the sample test or a src/test/examples.test.ts if the user asks for mocking examples.

Module mocking (vi.mock)
typescript
import { vi, describe, it, expect } from "vitest";
import { getUser } from "./api";

vi.mock("./api", () => ({
  getUser: vi.fn(),
}));

it("mocks a module function", async () => {
  vi.mocked(getUser).mockResolvedValue({ id: 1, name: "Test" });
  const user = await getUser(1);
  expect(user.name).toBe("Test");
  expect(getUser).toHaveBeenCalledWith(1);
});
Spy on methods (vi.spyOn)
typescript
it("spies on console.warn", () => {
  const spy = vi.spyOn(console, "warn").mockImplementation(() => {});
  doSomethingThatWarns();
  expect(spy).toHaveBeenCalledOnce();
  spy.mockRestore();
});
Fake timers
typescript
import { vi, beforeEach, afterEach, it, expect } from "vitest";

beforeEach(() => {
  vi.useFakeTimers();
  vi.setSystemTime(new Date("2026-01-15T10:00:00Z"));
});

afterEach(() => {
  vi.useRealTimers();
});

it("uses controlled time", () => {
  expect(new Date().toISOString()).toBe("2026-01-15T10:00:00.000Z");
});
Global stubs
typescript
it("stubs fetch", async () => {
  const mockFetch = vi.fn().mockResolvedValue({
    ok: true,
    json: () => Promise.resolve({ data: "test" }),
  });
  vi.stubGlobal("fetch", mockFetch);

  const res = await fetch("/api/data");
  expect(mockFetch).toHaveBeenCalledWith("/api/data");

  vi.unstubAllGlobals();
});
Snapshot testing
typescript
it("matches snapshot", () => {
  const result = generateConfig({ debug: true });
  expect(result).toMatchSnapshot();
});

it("matches inline snapshot", () => {
  expect({ status: "ok", count: 3 }).toMatchInlineSnapshot(`
    {
      "count": 3,
      "status": "ok",
    }
  `);
});
Parameterized tests
typescript
describe.each([
  { input: "hello", expected: "HELLO" },
  { input: "world", expected: "WORLD" },
  { input: "", expected: "" },
])("toUpperCase($input)", ({ input, expected }) => {
  it(`returns ${expected}`, () => {
    expect(input.toUpperCase()).toBe(expected);
  });
});

Jest Migration

When the detected project has Jest (jest.config.*, @types/jest, ts-jest in dependencies):

  1. Generate the vitest.config.ts using the steps above
  2. Update imports in existing test files:
typescript
// Before
import { jest } from "@jest/globals";
jest.mock("./api");
jest.fn();
jest.spyOn(obj, "method");

// After
import { vi } from "vitest";
vi.mock("./api");
vi.fn();
vi.spyOn(obj, "method");
  1. Remove Jest packages:
bash
pnpm remove jest ts-jest @types/jest jest-environment-jsdom babel-jest @jest/globals
  1. Update tsconfig — replace "types": ["jest"] with "types": ["vitest/globals"]

  2. Run tests and fix any remaining issues

Key replacements:

JestVitest
jest.fn()vi.fn()
jest.mock()vi.mock()
jest.spyOn()vi.spyOn()
jest.useFakeTimers()vi.useFakeTimers()
jest.clearAllMocks()vi.clearAllMocks()
jest.requireActual()vi.importActual()
@jest/globalsvitest
jest.config.jsvitest.config.ts

Workspace Setup (Monorepos)

For monorepo projects with multiple packages:

typescript
// vitest.workspace.ts
import { defineWorkspace } from "vitest/config";

export default defineWorkspace([
  "packages/*/vitest.config.ts",
]);

Each package gets its own config. The workspace file just points to them.


What This Skill Produces

After running, the project should have:

  • vitest.config.ts (or test block added to existing vite.config.ts)
  • src/test/setup.ts (React projects)
  • Updated tsconfig.json with vitest/globals type
  • Updated package.json with test scripts
  • At least one passing sample test against real source code
  • Dependencies installed

The tests should pass on first run. If they don't, fix them before finishing.

© jezweb, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in plugins/dev-tools/skills/vitest of jezweb/claude-skills.

Open the folder on GitHubat commit 64965d9

Compare with similar skills

Vitest next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Vitest compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Vitest this skilljezweb/claude-skills1.1k—~3kAutomated safety check: PassMIT
Vitest Skillsickn33/agentic-awesome-skills47k1 repos~1.2kAutomated safety check: PassMIT
Tooling SetupMadAppGang/claude-code284—~1.2kAutomated safety check: NotesMIT
Vitestsupabase/supabase111k12 repos~1.1kAutomated safety check: PassApache-2.0
Effect TStellahq/opensession392—~3.7kAutomated safety check: PassMIT
React Testinggetsentry/sentry46k—~2.2kAutomated safety check: PassCustom licence

Similar skills

  • Vitest Skill

    sickn33/agentic-awesome-skills

    Generates Vitest tests in JavaScript/TypeScript with Vite-native speed.

    47k GitHub starsUsed in 1 repo~1.2k tokens
    Testing & QAAuto-check passed
  • Tooling Setup

    MadAppGang/claude-code

    A skill your agent uses when setting up new projects or updating tool configurations.

    284 GitHub stars~1.2k tokensUpdated 6 mo ago
    Testing & QAAuto-check: notes
  • Vitest

    supabase/supabase

    Official

    Vitest API and config reference (Jest-compatible) — mocking with vi., spies, fake timers, coverage configuration, fixtures, snapshots, and test filtering.

    111k GitHub starsUsed in 12 repos~1.1k tokens
    Testing & QAAuto-check passed
  • Effect TS

    tellahq/opensession

    Write idiomatic Effect v4 TypeScript verified against the pinned effect@4.0.0-rc.112 source.

    392 GitHub stars~3.7k tokensUpdated today
    Testing & QAAuto-check passed
  • React Testing

    getsentry/sentry

    Official

    Write and review React/TypeScript tests for Sentry's frontend using Jest and React Testing Library.

    46k GitHub stars~2.2k tokensUpdated today
    Testing & QAAuto-check passed
  • Migrate an Nx repo package's unit tests from Jest to Vitest, reusing the shared setup that packages/workspace established.

    29k GitHub stars~7.3k tokensUpdated today
    Testing & QAAuto-check passed

More from jezweb/claude-skills

All 52 skills in this repo
  • Elevenlabs Agents

    jezweb/claude-skills

    Build conversational AI voice agents on the ElevenLabs platform.

    1.1k GitHub starsUsed in 1 repo~3.3k tokens
    Auto-check passed
  • Favicon Gen

    jezweb/claude-skills

    Generate custom favicons from logos, text, or brand colours.

    1.1k GitHub starsUsed in 1 repo~1k tokens
    Auto-check passed
  • Tailwind Theme Builder

    jezweb/claude-skills

    Set up Tailwind v4 + shadcn/ui themed UI with dark mode. An agent skill from jezweb/claude-skills.

    1.1k GitHub starsUsed in 1 repo~3.2k tokens
    Auto-check passed
  • Project Health

    jezweb/claude-skills

    All-in-one project configuration and health management. An agent skill from jezweb/claude-skills.

    1.1k GitHub starsUsed in 1 repo~3k tokens
    Auto-check passed
  • Responsiveness Check

    jezweb/claude-skills

    Test website responsiveness across viewport widths using browser automation.

    1.1k GitHub starsUsed in 1 repo~1.7k tokens
    Auto-check passed
  • MCP Builder

    jezweb/claude-skills

    Build MCP servers in Python with FastMCP. An agent skill from jezweb/claude-skills.

    1.1k GitHub stars~3.1k tokensUpdated 2 days ago
    Auto-check: notes

Categories

Questions about Vitest

What does Vitest do?

Set up Vitest testing in any project — detects type (Cloudflare Workers, React, Node, library), generates vitest.config.ts, test setup, utilities, and a sample test. Vitest is an agent skill from jezweb/claude-skills.ts, test setup, utilities, and a sample test.

When should I use Vitest?

Vitest fits situations like: the user mentions adding tests; setting up Vitest; configuring tests; migrating from Jest.

How do I install Vitest in Claude Code?

Run `npx skills add jezweb/claude-skills --skill vitest -a claude-code`. Or copy the skill folder (plugins/dev-tools/skills/vitest in jezweb/claude-skills) into .claude/skills/vitest in your project. Claude Code loads it when a task matches its description.

How do I install Vitest in Codex?

Run `npx skills add jezweb/claude-skills --skill vitest -a codex`. Or copy the skill folder (plugins/dev-tools/skills/vitest in jezweb/claude-skills) into .agents/skills/vitest in your project. Codex loads it when a task matches its description.

Can I use Vitest in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add jezweb/claude-skills --skill vitest -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/vitest, .gemini/skills/vitest, .github/skills/vitest and .opencode/skills/vitest in your project.

What does Vitest need to run?

Going by SKILL.md and its folder, Vitest needs the command-line tools its instructions call (pnpm).

Does Vitest access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Vitest safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Vitest use?

Vitest is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Vitest use?

About 3k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Vitest?

Skills that share tags, products or a category with Vitest: Vitest Skill (sickn33/agentic-awesome-skills, 47k stars), Tooling Setup (MadAppGang/claude-code, 284 stars), Vitest (supabase/supabase, 111k stars) and Effect TS (tellahq/opensession, 392 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Vitest?

jezweb (a GitHub user) maintains it in jezweb/claude-skills, which has 1,051 GitHub stars. The repository holds 52 skills in this directory. The repository was last updated on October 5, 2026.

Source: jezweb/claude-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.