Gojiberry AI
AI agents that find and contact high-intent leads for you
Try Gojiberry free →
Hermes Agent
Run your Hermes agent, fully managed
Launch on Hostinger →
Hostinger VPS
Spin up a VPS in one click, 20% off
Launch on Hostinger →
Firecrawl
Crawl and scrape any site into clean data
Try Firecrawl free →
Runable
One AI agent to build, run, and grow your business
Try Runable free →
Context.dev
One API to scrape, enrich, and extract the web
Start building free →
Jotform
Forms, workflows, and AI Agents for your team
Try Jotform free →
Runable
One AI agent to build, run, and grow your business
Try Runable free →
OpenClaw
Deploy a managed OpenClaw agent in 60 seconds
Launch on Hostinger →
Sponsor here
9/10 sponsor slots taken — 1 left
Claim it →
Claude Market
Menu
SkillsMCPPluginsMarketplacesNewsletterSubmit MCPSkillPluginMCPMCP, plugin, or skillAdvertise
Claude Market
SkillsMCPPluginsMarketplacesNewsletterSubmit MCPSkillPluginMCPMCP, plugin, or skillAdvertise
Skills/bobmatnyc/claude-mpm-skills/vitest
vitest logo

vitest

bobmatnyc/claude-mpm-skills
576 installs53 stars
Run it on Hostinger, 20% off →Your friend gets 20% off too, using this linkFree API →|View on GitHub|Create your own skill →

Installation

npx skills add https://github.com/bobmatnyc/claude-mpm-skills --skill vitest

Summary

Vitest - Modern TypeScript testing framework with Vite-native performance, ESM support, and TypeScript-first design

SKILL.md

Vitest - Modern TypeScript Testing

Overview

Vitest is a next-generation test framework powered by Vite, designed for modern TypeScript/JavaScript projects. It provides blazing-fast test execution through HMR-based test running, native ESM support, and first-class TypeScript integration.

Key Features:

  • ⚡ Vite-native: Instant HMR-based test execution (10-100x faster than Jest)
  • 🎯 TypeScript-first: Built-in TypeScript support, no configuration needed
  • 🔄 ESM-native: Native ES modules, async/await, top-level await
  • 🧪 Jest-compatible: Compatible API for easy migration
  • 📸 Snapshot testing: Built-in snapshot support
  • 🎨 Component testing: React Testing Library, Vue Test Utils integration
  • 📊 Coverage: Built-in v8/c8 coverage (faster than Istanbul)
  • 🌐 UI mode: Beautiful web UI for test debugging

Installation:

npm install -D vitest
# TypeScript types (usually auto-detected)
npm install -D @vitest/ui  # Optional: UI mode

Basic Setup

1. Configure Vitest

vitest.config.ts:

import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    globals: true,           // Use describe/it/expect globally
    environment: 'node',     // or 'jsdom' for DOM testing
    coverage: {
      provider: 'v8',        // or 'istanbul'
      reporter: ['text', 'json', 'html'],
      exclude: [
        'node_modules/',
        'dist/',
        '**/*.test.ts',
        '**/*.spec.ts',
      ],
    },
    include: ['**/*.{test,spec}.{ts,tsx}'],
    exclude: ['node_modules', 'dist', '.idea', '.git', '.cache'],
  },
});

2. TypeScript Configuration

tsconfig.json:

{
  "compilerOptions": {
    "types": ["vitest/globals"]  // For global describe/it/expect
  }
}

Alternative (without globals):

import { describe, it, expect } from 'vitest';

3. Package.json Scripts

{
  "scripts": {
    "test": "vitest run",              // CI mode (single run)
    "test:watch": "vitest",            // Watch mode (default)
    "test:ui": "vitest --ui",          // UI mode
    "test:coverage": "vitest run --coverage"
  }
}

Core Testing Patterns

Basic Test Structure

import { describe, it, expect, beforeEach, afterEach } from 'vitest';

describe('Calculator', () => {
  let calculator: Calculator;

  beforeEach(() => {
    calculator = new Calculator();
  });

  it('adds two numbers correctly', () => {
    const result = calculator.add(2, 3);
    expect(result).toBe(5);
  });

  it('handles negative numbers', () => {
    expect(calculator.add(-5, 3)).toBe(-2);
  });
});

TypeScript Type Testing

import { describe, it, expectTypeOf, assertType } from 'vitest';

interface User {
  id: number;
  name: string;
  email: string;
}

describe('Type Safety', () => {
  it('ensures correct types', () => {
    const user: User = {
      id: 1,
      name: 'Alice',
      email: 'alice@example.com',
    };

    // Type assertions
    expectTypeOf(user.id).toBeNumber();
    expectTypeOf(user.name).toBeString();
    expectTypeOf(user).toMatchTypeOf<User>();

    // Assert type at compile time
    assertType<User>(user);
  });

  it('checks function return types', () => {
    function getUser(): User {
      return { id: 1, name: 'Bob', email: 'bob@example.com' };
    }

    expectTypeOf(getUser).returns.toMatchTypeOf<User>();
  });
});

Mocking and Spies

vi.mock for Module Mocking

import { describe, it, expect, vi } from 'vitest';
import { fetchUser } from './api';
import { UserService } from './UserService';

// Mock entire module
vi.mock('./api', () => ({
  fetchUser: vi.fn(),
}));

describe('UserService', () => {
  it('fetches user data', async () => {
    const mockUser = { id: 1, name: 'Alice' };
    vi.mocked(fetchUser).mockResolvedValue(mockUser);

    const service = new UserService();
    const user = await service.getUser(1);

    expect(fetchUser).toHaveBeenCalledWith(1);
    expect(user).toEqual(mockUser);
  });
});

vi.spyOn for Method Spying

import { describe, it, expect, vi } from 'vitest';

class Logger {
  log(message: string) {
    console.log(message);
  }
}

describe('Logger Spy', () => {
  it('tracks method calls', () => {
    const logger = new Logger();
    const spy = vi.spyOn(logger, 'log');

    logger.log('Hello');
    logger.log('World');

    expect(spy).toHaveBeenCalledTimes(2);
    expect(spy).toHaveBeenCalledWith('Hello');
    expect(spy).toHaveBeenLastCalledWith('World');

    spy.mockRestore(); // Restore original implementation
  });
});

Mock Implementation

import { describe, it, expect, vi } from 'vitest';

describe('Mock Implementation', () => {
  it('provides custom mock implementation', () => {
    const mockFn = vi.fn((x: number) => x * 2);

    expect(mockFn(5)).toBe(10);
    expect(mockFn).toHaveBeenCalledWith(5);

    // Change implementation
    mockFn.mockImplementation((x: number) => x + 10);
    expect(mockFn(5)).toBe(15);

    // One-time implementation
    mockFn.mockImplementationOnce((x: number) => 100);
    expect(mockFn(5)).toBe(100);
    expect(mockFn(5)).toBe(15); // Back to default
  });
});

Mocking Timers

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';

describe('Timer Mocking', () => {
  beforeEach(() => {
    vi.useFakeTimers();
  });

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

  it('fast-forwards time', () => {
    const callback = vi.fn();
    setTimeout(callback, 1000);

    vi.advanceTimersByTime(500);
    expect(callback).not.toHaveBeenCalled();

    vi.advanceTimersByTime(500);
    expect(callback).toHaveBeenCalledTimes(1);
  });

  it('runs all timers', async () => {
    const callback = vi.fn();
    setTimeout(callback, 1000);
    setTimeout(callback, 2000);

    await vi.runAllTimersAsync();
    expect(callback).toHaveBeenCalledTimes(2);
  });
});

React Testing Integration

Setup React Testing Library

npm install -D @testing-library/react @testing-library/jest-dom @testing-library/user-event
npm install -D jsdom  # For DOM environment

vitest.config.ts (React):

import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';

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

src/test/setup.ts:

import '@testing-library/jest-dom';
import { expect, afterEach } from 'vitest';
import { cleanup } from '@testing-library/react';
import * as matchers from '@testing-library/jest-dom/matchers';

expect.extend(matchers);

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

React Component Testing

import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Counter } from './Counter';

describe('Counter Component', () => {
  it('renders initial count', () => {
    render(<Counter initialCount={0} />);
    expect(screen.getByText('Count: 0')).toBeInTheDocument();
  });

  it('increments counter on button click', async () => {
    const user = userEvent.setup();
    render(<Counter initialCount={0} />);

    const button = screen.getByRole('button', { name: /increment/i });
    await user.click(button);

    expect(screen.getByText('Count: 1')).toBeInTheDocument();
  });

  it('calls onChange callback', async () => {
    const onChange = vi.fn();
    const user = userEvent.setup();

    render(<Counter initialCount={0} onChange={onChange} />);

    await user.click(screen.getByRole('button', { name: /increment/i }));

    expect(onChange).toHaveBeenCalledWith(1);
  });
});

Testing Hooks

import { describe, it, expect } from 'vitest';
import { renderHook, act } from '@testing-library/react';
import { useCounter } from './useCounter';

describe('useCounter Hook', () => {
  it('initializes with default value', () => {
    const { result } = renderHook(() => useCounter(0));
    expect(result.current.count).toBe(0);
  });

  it('increments counter', () => {
    const { result } = renderHook(() => useCounter(0));

    act(() => {
      result.current.increment();
    });

    expect(result.current.count).toBe(1);
  });

  it('resets counter', () => {
    const { result } = renderHook(() => useCounter(10));

    act(() => {
      result.current.reset();
    });

    expect(result.current.count).toBe(10);
  });
});

Vue Testing Integration

Setup Vue Test Utils

npm install -D @vue/test-utils @vitejs/plugin-vue
npm install -D happy-dom  # Faster alternative to jsdom

vitest.config.ts (Vue):

import { defineConfig } from 'vitest/config';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [vue()],
  test: {
    globals: true,
    environment: 'happy-dom',
    setupFiles: './src/test/setup.ts',
  },
});

Vue Component Testing

import { describe, it, expect } from 'vitest';
import { mount } from '@vue/test-utils';
import Counter from './Counter.vue';

describe('Counter.vue', () => {
  it('renders initial count', () => {
    const wrapper = mount(Counter, {
      props: { initialCount: 5 },
    });

    expect(wrapper.text()).toContain('Count: 5');
  });

  it('increments on button click', async () => {
    const wrapper = mount(Counter, {
      props: { initialCount: 0 },
    });

    await wrapper.find('button').trigger('click');

    expect(wrapper.text()).toContain('Count: 1');
  });

  it('emits update event', async () => {
    const wrapper = mount(Counter, {
      props: { initialCount: 0 },
    });

    await wrapper.find('button').trigger('click');

    expect(wrapper.emitted('update')).toBeTruthy();
    expect(wrapper.emitted('update')?.[0]).toEqual([1]);
  });
});

Async Testing

Testing Promises

import { describe, it, expect } from 'vitest';

describe('Async Operations', () => {
  it('resolves promises', async () => {
    const result = await Promise.resolve(42);
    expect(result).toBe(42);
  });

  it('rejects promises', async () => {
    await expect(Promise.reject(new Error('Failed'))).rejects.toThrow('Failed');
  });

  it('uses resolves matcher', async () => {
    await expect(Promise.resolve(42)).resolves.toBe(42);
  });
});

Testing Async Functions

import { describe, it, expect, vi } from 'vitest';

async function fetchData(id: number): Promise<string> {
  const response = await fetch(`/api/data/${id}`);
  return response.json();
}

describe('Async Functions', () => {
  it('fetches data successfully', async () => {
    global.fetch = vi.fn(() =>
      Promise.resolve({
        json: () => Promise.resolve('data'),
      } as Response)
    );

    const data = await fetchData(1);
    expect(data).toBe('data');
    expect(fetch).toHaveBeenCalledWith('/api/data/1');
  });

  it('handles fetch errors', async () => {
    global.fetch = vi.fn(() => Promise.reject(new Error('Network error')));

    await expect(fetchData(1)).rejects.toThrow('Network error');
  });
});

Snapshot Testing

Basic Snapshots

import { describe, it, expect } from 'vitest';
import { render } from '@testing-library/react';
import { UserCard } from './UserCard';

describe('UserCard Snapshots', () => {
  it('matches snapshot', () => {
    const { container } = render(
      <UserCard name="Alice" email="alice@example.com" />
    );

    expect(container.firstChild).toMatchSnapshot();
  });

  it('matches inline snapshot', () => {
    const user = { id: 1, name: 'Bob' };
    expect(user).toMatchInlineSnapshot(`
      {
        "id": 1,
        "name": "Bob",
      }
    `);
  });
});

Snapshot Serializers

import { describe, it, expect } from 'vitest';

expect.addSnapshotSerializer({
  test: (val) => val && typeof val.toISOString === 'function',
  print: (val) => `Date(${(val as Date).toISOString()})`,
});

describe('Custom Serializers', () => {
  it('serializes dates consistently', () => {
    const data = {
      timestamp: new Date('2024-01-01T00:00:00.000Z'),
      user: 'Alice',
    };

    expect(data).toMatchSnapshot();
  });
});

Coverage Configuration

Advanced Coverage Setup

vitest.config.ts:

import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    coverage: {
      provider: 'v8',
      reporter: ['text', 'json', 'html', 'lcov'],
      reportsDirectory: './coverage',
      exclude: [
        'node_modules/',
        'dist/',
        '**/*.test.ts',
        '**/*.spec.ts',
        '**/*.config.ts',
        '**/types/',
      ],
      thresholds: {
        lines: 80,
        functions: 80,
        branches: 75,
        statements: 80,
      },
      all: true,  // Include untested files in coverage report
    },
  },
});

Running Coverage

# Generate coverage
npx vitest run --coverage

# Coverage with UI
npx vitest --coverage --ui

# Specific threshold enforcement
npx vitest run --coverage --coverage.lines=90

Migration from Jest

API Compatibility

Vitest provides Jest-compatible API:

// Jest syntax works in Vitest
import { describe, it, expect, jest } from 'vitest';

// Note: Use 'vi' instead of 'jest' for new code
import { describe, it, expect, vi } from 'vitest';

// Both work, but vi is preferred
const mockFn = vi.fn();  // Preferred
const mockFn2 = jest.fn();  // Also works

Migration Checklist

1. Update Dependencies:

npm uninstall jest @types/jest ts-jest
npm install -D vitest @vitest/ui

2. Update package.json:

{
  "scripts": {
    "test": "vitest run",  // Was: jest
    "test:watch": "vitest"  // Was: jest --watch
  }
}

3. Replace jest.config.js with vitest.config.ts:

// Old: jest.config.js
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
};

// New: vitest.config.ts
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    globals: true,
    environment: 'node',
  },
});

4. Update Test Files:

// Change imports
- import { jest } from '@jest/globals';
+ import { vi } from 'vitest';

// Update mocks
- jest.fn()
+ vi.fn()

- jest.spyOn()
+ vi.spyOn()

- jest.mock()
+ vi.mock()

Advanced Patterns

Concurrent Testing

import { describe, it, expect } from 'vitest';

describe.concurrent('Parallel Tests', () => {
  it('test 1', async () => {
    await slowOperation();
    expect(true).toBe(true);
  });

  it('test 2', async () => {
    await slowOperation();
    expect(true).toBe(true);
  });

  // Both tests run in parallel
});

Test Context

import { describe, it, expect, beforeEach } from 'vitest';

interface TestContext {
  user: { id: number; name: string };
  api: ApiClient;
}

describe<TestContext>('With Context', () => {
  beforeEach((context) => {
    context.user = { id: 1, name: 'Alice' };
    context.api = new ApiClient();
  });

  it<TestContext>('uses context', ({ user, api }) => {
    expect(user.name).toBe('Alice');
    expect(api).toBeDefined();
  });
});

Custom Matchers

import { expect } from 'vitest';

expect.extend({
  toBeWithinRange(received: number, floor: number, ceiling: number) {
    const pass = received >= floor && received <= ceiling;
    return {
      pass,
      message: () =>
        pass
          ? `expected ${received} not to be within range ${floor} - ${ceiling}`
          : `expected ${received} to be within range ${floor} - ${ceiling}`,
    };
  },
});

// Usage
expect(100).toBeWithinRange(90, 110);

Best Practices

  1. Use globals: true - Simpler imports, Jest-compatible
  2. Prefer vi over jest - Use Vitest-native API for new code
  3. Use v8 coverage - Faster than Istanbul, works with native ESM
  4. Test in isolation - Each test should be independent
  5. Mock external dependencies - Network, file system, timers
  6. Use TypeScript - Full type safety in tests
  7. Run tests in CI mode - Use vitest run for CI, not watch mode
  8. Leverage UI mode - Debug failing tests visually
  9. Use describe.concurrent - Parallelize independent tests
  10. Keep tests focused - One assertion per test when possible

Common Pitfalls

❌ Not using CI mode in CI/CD:

// WRONG - watch mode hangs in CI
"test": "vitest"

// CORRECT - single run
"test": "vitest run"

✅ Correct approach:

{
  "scripts": {
    "test": "vitest run",       // CI-safe
    "test:watch": "vitest",     // Development
    "test:ui": "vitest --ui"    // Debugging
  }
}

❌ Forgetting to await async tests:

// WRONG - test passes before assertion
it('fetches data', () => {
  fetchData().then(data => {
    expect(data).toBeDefined();  // Never runs!
  });
});

// CORRECT
it('fetches data', async () => {
  const data = await fetchData();
  expect(data).toBeDefined();
});

❌ Not cleaning up mocks:

// WRONG - mocks leak between tests
it('test 1', () => {
  vi.spyOn(console, 'log');
  // No cleanup!
});

// CORRECT
import { afterEach } from 'vitest';

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

❌ Using wrong environment:

// WRONG - testing DOM in node environment
test: {
  environment: 'node',  // Can't test React components!
}

// CORRECT
test: {
  environment: 'jsdom',  // For React/Vue components
}

Resources

  • Documentation: https://vitest.dev
  • API Reference: https://vitest.dev/api/
  • Migration Guide: https://vitest.dev/guide/migration.html
  • Examples: https://github.com/vitest-dev/vitest/tree/main/examples
  • UI Mode: https://vitest.dev/guide/ui.html

Related Skills

When using Vitest, consider these complementary skills:

  • typescript-core: Advanced TypeScript type patterns, tsconfig, and runtime validation
  • react: React component testing with Testing Library integration
  • test-driven-development: Complete TDD workflow (RED/GREEN/REFACTOR cycle)

Quick TypeScript Type Patterns (Inlined for Standalone Use)

// Type-safe test factories with generics
function createMockData<T extends Record<string, unknown>>(
  defaults: T,
  overrides?: Partial<T>
): T {
  return { ...defaults, ...overrides };
}

const mockUser = createMockData(
  { id: 1, name: 'Test', email: 'test@example.com' },
  { name: 'Alice' }
);

// Runtime validation with Zod in tests
import { z } from 'zod';

const UserSchema = z.object({
  id: z.number(),
  name: z.string(),
  email: z.string().email(),
});

test('API returns valid user', async () => {
  const response = await fetch('/api/user/1');
  const data = await response.json();

  // Runtime validation + type inference
  const user = UserSchema.parse(data);
  expect(user.email).toContain('@');
});

// Const type parameters for literal inference
const createTestConfig = <const T extends Record<string, unknown>>(config: T): T => config;
const testEnv = createTestConfig({ mode: 'test', debug: false });
// Type: { mode: "test"; debug: false } (literals preserved)

Quick React Testing Patterns (Inlined for Standalone Use)

// React Testing Library with Vitest
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { userEvent } from '@testing-library/user-event';
import { describe, test, expect, vi } from 'vitest';

// Component testing
describe('UserProfile', () => {
  test('renders user information', () => {
    const user = { id: 1, name: 'Alice', email: 'alice@example.com' };
    render(<UserProfile user={user} />);

    expect(screen.getByText('Alice')).toBeInTheDocument();
    expect(screen.getByText('alice@example.com')).toBeInTheDocument();
  });

  test('handles form submission', async () => {
    const onSubmit = vi.fn();
    render(<UserForm onSubmit={onSubmit} />);

    const user = userEvent.setup();
    await user.type(screen.getByLabelText('Name'), 'Bob');
    await user.click(screen.getByRole('button', { name: 'Submit' }));

    await waitFor(() => {
      expect(onSubmit).toHaveBeenCalledWith({ name: 'Bob' });
    });
  });
});

// Hook testing
import { renderHook, act } from '@testing-library/react';

test('useCounter hook increments', () => {
  const { result } = renderHook(() => useCounter(0));

  expect(result.current.count).toBe(0);

  act(() => {
    result.current.increment();
  });

  expect(result.current.count).toBe(1);
});

Quick TDD Workflow Reference (Inlined for Standalone Use)

RED → GREEN → REFACTOR Cycle:

  1. RED Phase: Write Failing Test
   test('should authenticate user with valid credentials', () => {
     const user = { username: 'alice', password: 'secret123' };
     const result = authenticate(user);
     expect(result.isAuthenticated).toBe(true);
     // This fails because authenticate() doesn't exist yet
   });
  1. GREEN Phase: Make It Pass
   function authenticate(user: User): AuthResult {
     // Minimum code to pass the test
     if (user.username === 'alice' && user.password === 'secret123') {
       return { isAuthenticated: true };
     }
     return { isAuthenticated: false };
   }
  1. REFACTOR Phase: Improve Code
   function authenticate(user: User): AuthResult {
     // Clean up while keeping tests green
     const hashed = hashPassword(user.password);
     const storedUser = database.getUser(user.username);
     return {
       isAuthenticated: storedUser?.passwordHash === hashed
     };
   }

Test Structure: Arrange-Act-Assert (AAA)

test('creates user successfully', async () => {
  // Arrange: Set up test data
  const userData = { username: 'alice', email: 'alice@example.com' };

  // Act: Perform the action
  const user = await createUser(userData);

  // Assert: Verify outcome
  expect(user.username).toBe('alice');
  expect(user.email).toBe('alice@example.com');
});

Vitest-Specific TDD Features:

// Watch mode with HMR (instant feedback)
// vitest --watch

// UI mode for visual debugging
// vitest --ui

// Run only changed tests
// vitest --changed

// Benchmark mode for performance testing
import { bench } from 'vitest';

bench('authenticate performance', () => {
  authenticate({ username: 'alice', password: 'secret' });
});

[Full TypeScript, React, and TDD workflows available in respective skills if deployed together]

Summary

  • Vitest is the modern standard for TypeScript testing
  • 10-100x faster than Jest through Vite-native HMR
  • ESM-first with native module support
  • Jest-compatible API for easy migration
  • TypeScript-first with built-in type support
  • Component testing for React and Vue
  • v8 coverage faster than Istanbul
  • UI mode for visual test debugging
  • Perfect for: Modern TypeScript projects, Vite-based apps, React/Vue components

Score

0–100
63/ 100

Grade

C

Popularity15/30

576 installs — growing adoption.

Completeness27/30

Documented: full SKILL.md body, description, one-line install. Missing: category/license metadata.

Trust15/25

Community skill with a public GitHub source repository you can review.

Freshness6/15

No update timestamp is tracked for this skill in our catalog.

Scored automatically from popularity, completeness, trust, and freshness — computed only from data in our catalog, never fabricated.

Proud of your score? Add this badge to your README.

Paste a snippet into your GitHub README. The badge updates automatically and links back to this page.

Vitest skill score badge previewScore badge

Markdown

[![Vitest skill](https://www.claudemarket.ai/skills/bobmatnyc/claude-mpm-skills/vitest/badges/score.svg)](https://www.claudemarket.ai/skills/bobmatnyc/claude-mpm-skills/vitest)

HTML

<a href="https://www.claudemarket.ai/skills/bobmatnyc/claude-mpm-skills/vitest"><img src="https://www.claudemarket.ai/skills/bobmatnyc/claude-mpm-skills/vitest/badges/score.svg" alt="Vitest skill"/></a>

Vitest FAQ

How do I install the Vitest skill?

Run “npx skills add https://github.com/bobmatnyc/claude-mpm-skills --skill vitest” in your terminal. The skill is added to your agent's skills directory and picked up automatically on the next run — no restart or extra configuration needed.

What does the Vitest skill do?

Vitest - Modern TypeScript testing framework with Vite-native performance, ESM support, and TypeScript-first design The full SKILL.md on this page shows the exact instructions the skill gives your agent.

Is the Vitest skill free?

Yes. Vitest is a free, open-source skill published from bobmatnyc/claude-mpm-skills. As with any third-party skill, review the source repository before installing it into an agent with sensitive access.

Does Vitest work with Claude Code and OpenClaw?

Yes. Skills use the portable SKILL.md format, so Vitest works with Claude Code, OpenClaw, Codex, Hermes, and any other agent that reads SKILL.md skills.

Recommended skills

Browse all →
find-skills logo

find-skills

vercel-labs/skills

2.9M installsInstall
grill-me logo

grill-me

mattpocock/skills

816K installsInstall
frontend-design logo

frontend-design

anthropics/skills

761K installsInstall
grill-with-docs logo

grill-with-docs

mattpocock/skills

695K installsInstall
improve-codebase-architecture logo

improve-codebase-architecture

mattpocock/skills

670K installsInstall
agent-browser logo

agent-browser

vercel-labs/agent-browser

651K installsInstall

Related guides

Hand-picked reading to help you choose, install, and use agent skills.

GuideBest Testing Skills For AI AgentsGuide10 Openclaw Skills Every Nextjs Developer NeedsGuideBest Openclaw Skills 2026

Skills by category

FrontendBackend & APIsTesting & QASecurityDevOps & CI/CDMCP & ToolingAutomationData & Analysis+27 more

MCP servers by category

MCP & ToolingBackend & APIsData & AnalysisDevOps & CI/CDAutomationSecurityDocsTesting & QA+24 more

Plugins by category

AutomationDevOps & CI/CDData & AnalysisDesign & CreativeSecurityBackend & APIsFrontendTesting & QA+16 more

Marketplaces by category

AutomationData & AnalysisDevOps & CI/CDDesign & CreativeFrontendBackend & APIsTesting & QASecurity+21 more

The Agent Stack

Weekly Claude Code, Agent SDK, and MCP moves worth your time — free.

Claude Market

AI agent skills directory, marketplace, and workflow hub for OpenClaw, Hermes Agent, Claude Code, Codex, and MCP-powered operator stacks.

Independent project, not affiliated with Anthropic.

Resources

  • Browse Skills
  • Browse MCP Servers
  • Browse Plugins
  • Browse Marketplaces
  • Newsletter

More

  • Submit a Tool
  • Create a Skill
  • Advertise
  • Free Tools
  • API
  • Shipping
  • Contact
  • Terms
  • Privacy
© 2026 Claude Market · Not affiliated with Anthropic
Fazier badgeFeatured on Twelve ToolsFeatured on Wired BusinessRemote OpenClaw - Featured on AI Agents DirectoryListed on Turbo0Featured on Uneed