> bun-jest-migration
Use when migrating from Jest to Bun's test runner, import compatibility, mocks, and config.
curl "https://skillshub.wtf/secondsky/claude-skills/bun-jest-migration?format=md"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
| Jest | Bun | Notes |
|---|---|---|
describe() | describe() | Identical |
it() / test() | test() | Use test() |
expect() | expect() | Same matchers |
beforeAll/Each | beforeAll/Each | Identical |
afterAll/Each | afterAll/Each | Identical |
jest.fn() | mock() | Use mock() |
jest.spyOn() | spyOn() | Identical |
Requires Changes
| Jest | Bun 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
-
Remove Jest packages
bun remove jest ts-jest @types/jest babel-jest jest-environment-jsdom -
Update package.json
{ "scripts": { "test": "bun test", "test:watch": "bun test --watch", "test:coverage": "bun test --coverage" } } -
Convert jest.config.js to bunfig.toml
-
Update imports in test files
- Find/replace
@jest/globals→bun:test - Find/replace
jest.fn()→mock() - Find/replace
jest.mock()→mock.module()
- Find/replace
-
Run and fix
bun test 2>&1 | head -50 # Check first errors
Common Errors
| Error | Cause | Fix |
|---|---|---|
Cannot find module '@jest/globals' | Old import | Use bun:test |
jest is not defined | Global jest | Import from bun:test |
mock.module is not a function | Wrong import | import { mock } from "bun:test" |
Snapshot mismatch | Different serialization | Update 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