ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 47

  1. Blog

bun test vs Vitest: 136ms vs 1.67s on 300 Tests

bun test 1.4.2 vs Vitest 5.0.3 on 300 TypeScript tests in 60 files: warm wall medians 136 ms vs 1,673 ms (~12x); Vitest --no-isolate 765 ms (~5.6x). A 5-file vitest-API check (vi.fn, vi.mock, fake timers, spyOn, it.each, snapshot) passed 7/7 under Bun.

Aditya Challa·5 October 2026·5 min read

Hands-on
On this page
  1. What I tested
  2. Is bun test faster than Vitest on the same suite?
  3. Will my Vitest tests run under bun test without edits?
  4. Does isolation explain the whole gap?
  5. Should you switch from Vitest to bun test?
  6. Sources
  7. Related

I ran the same 300 TypeScript unit tests in 60 files under bun test 1.4.2 and Vitest 5.0.3: bun test finished in a 136 ms wall-clock median, Vitest took 1.67 s with default isolation and 765 ms with --no-isolate. That is about 12x against default Vitest and about 5.6x against the fairer no-isolate setting, and all 300 tests passed under both.

Short answer: try bun test for plain Node-style unit suites where you do not lean on Vite plugins or a DOM environment. Stay on Vitest when your tests depend on vitest.config transforms, aliases, browser mode, or coverage you already trust. No affiliate links in this post.

What I tested

  • Machine: 8 vCPU Intel Xeon / 15 GB RAM shared Linux cloud box, tested 5 Oct 2026 (about 23:59 IST to 00:05 IST on 6 Oct).
  • Versions: Bun 1.4.2, Vitest 5.0.3 on Node 22.20.0. Vitest 5 declares Node ^22.12, ^24 or 26+, so Node 20 is out.
  • Fixture: /workspace/bench-bun-vitest/. 60 source modules in TypeScript, 60 test files, 5 tests each (toHaveLength, toEqual, toBeGreaterThan, an async resolves check with a 1 ms timer, toStrictEqual). Vitest config: environment node, globals on.
  • Timing: wall clock around each process, called directly (no npx). One warm-up, then 9 interleaved rounds. A separate cold series of 5 cleared node_modules/.vite and node_modules/.vitest before each Vitest run and set BUN_RUNTIME_TRANSPILER_CACHE_PATH=0 for Bun.
  • Findings: warm medians bun test 136 ms, Vitest 1,673 ms, Vitest --no-isolate 765 ms. Cold medians 135 ms and 1,728 ms. Clearing caches barely moved either tool.
  • One surprise: a separate 5-file check that imports from "vitest" (vi.fn, vi.mock, vi.useFakeTimers, vi.spyOn, it.each, toMatchSnapshot) passed 7/7 under bun test with no edits.
  • Not tested: jsdom or happy-dom, coverage, Vitest browser mode, watch-mode reruns, path aliases or Vite plugins, suites with heavy real I/O, Windows or macOS.

Is bun test faster than Vitest on the same suite?

Run (300 tests, 60 files)bun test 1.4.2Vitest 5.0.3 defaultVitest 5.0.3 --no-isolate
Warm wall median (9 runs)136 ms1,673 ms765 ms
Cold wall median (5 runs, caches cleared)135 ms1,728 msnot run
Tests passed300/300300/300300/300
Runtime neededBun binary onlyNode 22.12+Node 22.12+

Yes, by a wide margin on this fixture. Vitest itself printed why the default is slow here: it spawned 60 workers at roughly 95 ms of startup each, one per file. Bun runs the files in one process, so the closest Vitest setting is --no-isolate, and the gap there is still about 5.6x.

If you are still choosing between Jest and Vitest, my Jest vs Vitest numbers show the same isolation cost from the other side. The Vitest 5 upgrade post covers the Node 22 engine gate in more detail.

Will my Vitest tests run under bun test without edits?

The basic ones did. My compat files used vi.fn with mock.results, a hoisted vi.mock of a local module, fake timers with advanceTimersByTime, vi.spyOn with mockReturnValue, it.each, and a file snapshot. Bun passed all 7 tests and Vitest passed the same 7.

Where I would expect trouble: anything configured in vitest.config, because bun test does not read it. Aliases, setupFiles, Vite plugins such as Vue or Svelte transforms, and environment: jsdom all need Bun-side equivalents. My jsdom vs happy-dom test is the place to start if your suite needs a DOM.

Does isolation explain the whole gap?

No. Turning isolation off halved Vitest's time, from 1,673 ms to 765 ms, but Bun was still about 630 ms faster. The rest is Vite's transform pipeline and Node worker startup versus Bun's built-in TypeScript transpiler.

The trade-off is real. With one process, a test that mutates a global or leaves a module mock behind can leak into the next file. Vitest's default isolation exists to stop that. If your suite has a history of order-dependent failures, the 12x number overstates what you can safely bank.

Should you switch from Vitest to bun test?

SituationMy pick
Pure TS or JS unit tests, no DOM, no Vite pluginsTry bun test
Already using Bun as the package manager or runtimebun test
Vue, Svelte or other Vite-plugin transforms in testsStay on Vitest
jsdom or happy-dom component testsStay on Vitest for now
Coverage thresholds wired into CIStay on Vitest until you re-check coverage numbers
Stuck on Node 20bun test (Vitest 5 needs Node 22.12+)

Bottom line: 136 ms against 1.67 s is a real difference in a tight edit-and-rerun loop, and the API overlap was better than I expected. Who should not switch yet: teams whose tests depend on vitest.config, browser mode, or DOM environments, because none of that carries over. For install speed with Bun versus pnpm and npm, see pnpm vs npm vs Bun; for what changed in the runtime itself, see the Bun 1.4.2 notes.

How this was made: I generated a 60-file TypeScript suite on the ShopperCove test box, timed interleaved bun test and Vitest runs, ran a small vitest-API compat check under Bun, and kept the JSON; the write-up was drafted with AI help and checked against that output.

Sources

  • https://bun.sh/docs/cli/test
  • https://bun.sh/docs/test/writing
  • https://vitest.dev/guide/
  • https://vitest.dev/config/
  • https://www.npmjs.com/package/vitest
  • https://github.com/oven-sh/bun

Related

  • https://www.shoppercove.com/blog/jest-vs-vitest
  • https://www.shoppercove.com/blog/vitest-5-should-you-upgrade-october-2026
  • https://www.shoppercove.com/blog/jsdom-vs-happy-dom-vitest
  • https://www.shoppercove.com/blog/pnpm-vs-npm-vs-bun
  • https://www.shoppercove.com/blog/bun-1-4-2-elysia-als-cmyk-jpeg-october-2026
  • https://www.shoppercove.com/blog/c8-vs-nyc
  • https://www.shoppercove.com/blog/msw-vs-nock
  • https://www.shoppercove.com/blog/tsx-vs-ts-node
bun testvitestunit testingperformancetypescriptbenchmarkingnode.js

Lab evidence

What I found running this

Hands-on on ShopperCove box 5 Oct 2026 ~23:59 IST to 6 Oct ~00:05 IST (8 vCPU Intel Xeon / 15 GB shared Linux). Bun 1.4.2; Vitest 5.0.3 on Node 22.20.0 (Vitest 5 engines Node ^22.12 || ^24 || >=26). Fixture: /workspace/bench-bun-vitest/ - 60 TS modules + 60 test files x 5 tests, environment node, globals. Direct binaries, no npx. 1 warm-up + 9 interleaved rounds: warm medians bun 136 ms, vitest 1673 ms, vitest --no-isolate 765 ms. 5 cold rounds (cleared node_modules/.vite + .vitest; BUN_RUNTIME_TRANSPILER_CACHE_PATH=0): 135 ms vs 1728 ms. All 300/300 pass. Compat dir (5 files importing from vitest) passed 7/7 under bun test and Vitest. Raw: /workspace/bench-bun-vitest/res-bun-vitest.json (npx-inclusive first run in res-bun-vitest-npx.json). Not tested: jsdom/happy-dom, coverage, browser mode, watch, aliases/Vite plugins, heavy I/O, Windows/macOS. No affiliate.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Related links

  • Plate 46

    esbuild-register vs jiti: 343ms vs 540ms Cold

    esbuild-register 3.6.0 vs jiti 2.7.0 on a 61-file TypeScript graph: cold wall medians 343 ms vs 540 ms (~1.57x); after jiti disk cache warm, 185 ms vs esbuild-register 350 ms. Same printed result 970.

    5 Oct 2026

  • Plate 21

    Vitest 5.0.3 vs 4.1.10: Should You Upgrade? (20-File Timing)

    Vitest 5 upgrade decision with ShopperCove timing: 20-file forks suite median ~512 ms on 5.0.3 vs ~547 ms on 4.1.10 (Node 22.20.0). Engines require Node 22.12+ and Vite 6.4+. clearMocks defaults true. No affiliate.

    5 Oct 2026

  • Plate 69

    oxlint vs ESLint: Should You Switch? 9.8s vs 0.09s

    oxlint 1.87.0 vs ESLint 9.39.4 on react-hook-form (301 files): 0.09 s vs 9.81 s single-thread (6.02 s with --concurrency auto, 1.10 s warm --cache). @oxlint/migrate ported 42 of 84 rules natively, 80 with JS plugins. 315 vs 562 warnings; seeded test 11/15 native, 13/15 with JS plugins, ESLint 15/15.

    5 Oct 2026

On this page

  1. What I tested
  2. Is bun test faster than Vitest on the same suite?
  3. Will my Vitest tests run under bun test without edits?
  4. Does isolation explain the whole gap?
  5. Should you switch from Vitest to bun test?
  6. Sources
  7. Related
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove