Skip to content
Development
Skill

/bun-jest-migration

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

From plugin
secondsky-claude-skills
219183 skills42 agents62 commands2 MCP
Install
$ npx -y skills add secondsky/claude-skills --skill bun-jest-migration --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/bun-jest-migration

Context preview

The summary Claude sees to decide when to auto-load this skill.

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

SKILL.md

bun-jest-migration.SKILL.md
name: bun-jest-migration
description: Use when migrating from Jest to Bun's test runner, import compatibility, mocks, and config.
metadata:
  version: "1.0.0"
license: MIT

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

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/globals` → `bun: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

| 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
Read more
Ships withsecondsky-claude-skills

145 production-ready skills for Claude Code CLI 🔌 Platform / Harness Support These plugins ship as Claude Code marketplace plugins (.claude-plugin/ manifests) and Codex CLI plugins (.codex-plugin/ manifests).

Get the whole plugin

Other skills on secondsky-claude-skills.