> bun-jest-migration

Use when migrating from Jest to Bun's test runner, import compatibility, mocks, and config.

fetch
$curl "https://skillshub.wtf/secondsky/claude-skills/bun-jest-migration?format=md"
SKILL.mdbun-jest-migration

Bun Jest Migration

Bun's test runner is Jest-compatible. Most Jest tests run without changes.

Quick Migration

# 1. Remove Jest dependencies
bun remove jest ts-jest @types/jest babel-jest

# 2. Update test script
# package.json: "test": "bun test"

# 3. Run tests
bun test

Import Changes

// Before (Jest)
import { describe, it, expect, jest } from '@jest/globals';

// After (Bun) - No import needed, or explicit:
import { describe, test, expect, mock, spyOn } from "bun:test";

API Compatibility

Fully Compatible

JestBunNotes
describe()describe()Identical
it() / test()test()Use test()
expect()expect()Same matchers
beforeAll/EachbeforeAll/EachIdentical
afterAll/EachafterAll/EachIdentical
jest.fn()mock()Use mock()
jest.spyOn()spyOn()Identical

Requires Changes

JestBun Equivalent
jest.mock('module')mock.module('module', () => {...})
jest.useFakeTimers()import { setSystemTime } from "bun:test"
jest.setTimeout()Third argument to test()
jest.clearAllMocks()Call .mockClear() on each mock

Mock Migration

Mock Functions

// Jest
const fn = jest.fn().mockReturnValue('value');

// Bun
const fn = mock(() => 'value');
// Or for compatibility:
import { jest } from "bun:test";
const fn = jest.fn(() => 'value');

Module Mocking

// Jest (top-level hoisting)
jest.mock('./utils', () => ({
  helper: jest.fn(() => 'mocked')
}));

// Bun (inline, no hoisting)
import { mock } from "bun:test";
mock.module('./utils', () => ({
  helper: mock(() => 'mocked')
}));

Spy Migration

// Jest
jest.spyOn(console, 'log').mockImplementation(() => {});

// Bun (identical)
spyOn(console, 'log').mockImplementation(() => {});

Timer Migration

// Jest
jest.useFakeTimers();
jest.setSystemTime(new Date('2024-01-01'));
jest.advanceTimersByTime(1000);

// Bun - supports Jest-compatible timer APIs
import { setSystemTime } from "bun:test";
import { jest } from "bun:test";

jest.useFakeTimers();
jest.setSystemTime(new Date('2024-01-01'));
jest.advanceTimersByTime(1000);  // Now supported

Snapshot Testing

// Jest
expect(component).toMatchSnapshot();
expect(data).toMatchInlineSnapshot(`"expected"`);

// Bun (identical)
expect(component).toMatchSnapshot();
expect(data).toMatchInlineSnapshot(`"expected"`);

Update snapshots:

bun test --update-snapshots

Configuration Migration

jest.config.js → bunfig.toml

// jest.config.js (before)
module.exports = {
  testMatch: ['**/*.test.ts'],
  testTimeout: 10000,
  setupFilesAfterEnv: ['./jest.setup.ts'],
  collectCoverage: true,
  coverageThreshold: { global: { lines: 80 } }
};
# bunfig.toml (after)
[test]
root = "./"
preload = ["./jest.setup.ts"]
timeout = 10000
coverage = true
coverageThreshold = 0.8

Common Migration Issues

Issue: jest.mock Not Working

// Jest mock hoisting doesn't exist in Bun
// Move mock.module before imports or use dynamic imports

// Solution 1: Use mock.module at top
mock.module('./api', () => ({ fetch: mock() }));
import { fetch } from './api';

// Solution 2: Dynamic import
const mockFetch = mock();
mock.module('./api', () => ({ fetch: mockFetch }));
const { fetch } = await import('./api');

Issue: Timer Functions Missing

// Bun timer support is limited
// Use setSystemTime for date mocking
import { setSystemTime } from "bun:test";

beforeEach(() => {
  setSystemTime(new Date('2024-01-01'));
});

afterEach(() => {
  setSystemTime(); // Reset to real time
});

Issue: Custom Matchers

// Jest
expect.extend({ toBeWithinRange(received, floor, ceiling) {...} });

// Bun (same API)
import { expect } from "bun:test";
expect.extend({
  toBeWithinRange(received, floor, ceiling) {
    const pass = received >= floor && received <= ceiling;
    return {
      pass,
      message: () => `expected ${received} to be within ${floor}-${ceiling}`
    };
  }
});

Step-by-Step Migration

  1. Remove Jest packages

    bun remove jest ts-jest @types/jest babel-jest jest-environment-jsdom
    
  2. Update package.json

    {
      "scripts": {
        "test": "bun test",
        "test:watch": "bun test --watch",
        "test:coverage": "bun test --coverage"
      }
    }
    
  3. Convert jest.config.js to bunfig.toml

  4. Update imports in test files

    • Find/replace @jest/globalsbun:test
    • Find/replace jest.fn()mock()
    • Find/replace jest.mock()mock.module()
  5. Run and fix

    bun test 2>&1 | head -50  # Check first errors
    

Common Errors

ErrorCauseFix
Cannot find module '@jest/globals'Old importUse bun:test
jest is not definedGlobal jestImport from bun:test
mock.module is not a functionWrong importimport { mock } from "bun:test"
Snapshot mismatchDifferent serializationUpdate with --update-snapshots

When to Load References

Load references/compatibility-matrix.md when:

  • Full Jest API compatibility details
  • Unsupported features list
  • Workarounds for missing features

> related_skills --same-repo

> zustand-state-management

--- name: zustand-state-management description: Zustand state management for React with TypeScript. Use for global state, Redux/Context API migration, localStorage persistence, slices pattern, devtools, Next.js SSR, or encountering hydration errors, TypeScript inference issues, persist middleware problems, infinite render loops. Keywords: zustand, state management, React state, TypeScript state, persist middleware, devtools, slices pattern, global state, React hooks, create store, useBoundS

> zod

TypeScript-first schema validation and type inference. Use for validating API requests/responses, form data, env vars, configs, defining type-safe schemas with runtime validation, transforming data, generating JSON Schema for OpenAPI/AI, or encountering missing validation errors, type inference issues, validation error handling problems. Zero dependencies (2kb gzipped).

> xss-prevention

--- name: xss-prevention description: XSS attack prevention with input sanitization, output encoding, Content Security Policy. Use for user-generated content, rich text editors, web application security, or encountering stored XSS, reflected XSS, DOM manipulation, script injection errors. Keywords: sanitization, HTML-encoding, DOMPurify, CSP, Content-Security-Policy, rich-text-editor, user-input, escaping, innerHTML, DOM-manipulation, stored-XSS, reflected-XSS, input-validation, output-encodi

> wordpress-plugin-core

--- name: wordpress-plugin-core description: WordPress plugin development with hooks, security, REST API, custom post types. Use for plugin creation, $wpdb queries, Settings API, or encountering SQL injection, XSS, CSRF, nonce errors. Keywords: wordpress plugin development, wordpress security, wordpress hooks, wordpress filters, wordpress database, wpdb prepare, sanitize_text_field, esc_html, wp_nonce, custom post type, register_post_type, settings api, rest api, admin-ajax, wordpress sql inj

┌ stats

installs/wk0
░░░░░░░░░░
github stars101
██████████
first seenApr 3, 2026
└────────────