
The advice for 2026 is tidy and everywhere: use Vite, and use Vitest to test. They come as a matched set in every starter guide. So when I migrated my site off Create React App and onto Vite, the obvious next step was to switch my tests to Vitest too.
I didn't. I moved to Vite and kept Jest, on purpose. I still think it was the right call, and the reason is a distinction people skip past.
Your build tool and your test runner are two different decisions
Vite is a build tool. Its job is to bundle and serve your app. Jest and Vitest are test runners. Their job is to execute your tests. People bundle these two decisions together because the tools ship in the same tutorials, but nothing forces them to move as a pair. You can absolutely build with Vite and test with Jest. I do.
Once you separate the two decisions, the Vitest switch has to justify itself on its own. For my project, it couldn't.
What switching would have actually cost
Here is the part the "just switch" advice never mentions. My test suite was not small. At the time of the migration it was hundreds of tests across dozens of files, with 326 jest.* calls scattered through them. That is 326 places using Jest's specific API for mocks, spies, timers, and module mocking.
Vitest is close to Jest on purpose, but close is not identical. Migrating means touching every one of those call sites, re-checking mocking behavior that differs in subtle ways, and re-verifying that a large, working, green suite is still green afterward. That is real risk, spent on tests that already worked.
My CI made the math worse. It runs Jest with Jest-specific flags like --testPathPattern, --watchAll, and --maxWorkers. Switching runners means rewriting those pipeline commands too. So the "small" change ripples out into the suite and the CI config at the same time.
Add it up and the honest question is: what do I get back for all that work? For my site, the answer was nothing my users or I would ever notice. Faster test startup in exchange for a risky migration of a suite that was not slow enough to hurt. That is a bad trade.
The one real friction, and how I handled it
Keeping Jest was not completely free. Jest cannot parse import.meta, which Vite uses for environment variables. My app reads config through import.meta.env, and Jest chokes on that syntax.
I did not switch runners to fix it. I pointed Jest at a small process.env-backed version of my env module through moduleNameMapper, so Jest and the browser stay on matching code paths. One shim, isolated to config, versus migrating 326 call sites. That is the whole trade in miniature: a tiny targeted fix beats a large migration almost every time. The rest of the Jest config stayed boring on purpose: babel-jest with inline presets, jsdom, my CSS and asset stubs. All of it kept working, and the suite stayed green through the entire Vite move.
How the decision aged
This is the part I could not have known at the time but am glad about now. That suite did not stay the same size. It has since grown well past a thousand tests as I kept building features and adding coverage. Every one of those tests is a Jest test, written against the runner I chose to keep, which means every one of them would have been part of the migration bill I never paid. The single import.meta shim is still the only concession. A decision that saves you a little today and keeps saving you as the thing it touches grows is the kind of decision worth making deliberately.
When I would actually switch
I am not anti-Vitest. If I were starting a new project today, I would very likely start with Vitest, because greenfield has no migration cost and the Vite integration is genuinely nice. I would also switch an existing suite if I hit a real wall: ESM-only dependencies that Jest cannot handle cleanly, or a genuine need for tests to run through Vite's own transform pipeline. None of those were true for me. So the tool that already worked kept working.
The actual lesson
The useful habit here is not "keep Jest." It is refusing to migrate something just because it now sits next to a tool you adopted. New build tool does not automatically mean new test runner, new state library, or new anything else. Each change should earn its place by fixing a problem you actually have. My site got faster builds from Vite, which was the problem I wanted to solve. My tests kept running on Jest, because they were never the problem. Two decisions, made separately, and the site is better for both.