Skip to content
Back to skills

Bun Jest Migration

ASecurity

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

  • 222 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added February 7, 2026
developmentjavascripttypescriptjavabashtestingapi

Works with

  • api

Security analysis

A100/100

Scanned February 12, 2026

npx -y skills add secondsky/claude-skills --skill bun-jest-migration --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Bun Jest Migration?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Bun Jest Migration
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/secondsky-bun-jest-migration/badge)](https://www.skillsdirectory.com/skills/secondsky-bun-jest-migration)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: Bun Jest Migration
description: Use when migrating from Jest to Bun's test runner, import compatibility, mocks, and config.
version: 1.0.0
---

# Bun Jest Migration

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

## Quick Migration

```bash
# 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

```typescript
// 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

```typescript
// 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

```typescript
// 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

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

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

## Timer Migration

```typescript
// 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

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

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

Update snapshots:
```bash
bun test --update-snapshots
```

## Configuration Migration

### jest.config.js → bunfig.toml

```javascript
// jest.config.js (before)
module.exports = {
  testMatch: ['**/*.test.ts'],
  testTimeout: 10000,
  setupFilesAfterEnv: ['./jest.setup.ts'],
  collectCoverage: true,
  coverageThreshold: { global: { lines: 80 } }
};
```

```toml
# bunfig.toml (after)
[test]
root = "./"
preload = ["./jest.setup.ts"]
timeout = 10000
coverage = true
coverageThreshold = 0.8
```

## Common Migration Issues

### Issue: `jest.mock` Not Working

```typescript
// 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

```typescript
// 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

```typescript
// 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**
   ```bash
   bun remove jest ts-jest @types/jest babel-jest jest-environment-jsdom
   ```

2. **Update package.json**
   ```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**
   ```bash
   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

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…