Viteās been taking the world by storm since early 2021. It dramatically simplified developer tooling and became the underpinning of several popular metaframeworks. Now, itās ready to take over our test suites via Vitest. š®
Letās discuss how Vitest works, compare it with a popular test suite configuration (Jest and Babel), explore the ways Vitest can simplify your test suite config, and examine how the performance gains can speed up your watch mode. If youād like to jump around to sections of interest, click on the links below:
Viteās value proposition has become so broad that itās hard to pin down. To summarize: Vite is a website bundler that can handle your JavaScript, your CSS, your static assets, and just about anything you load into an HTML document.
Remember Appleās original value proposition for the iPhone, āAn iPod, a phone, an Internet communicatorā¦ā? I see Vite as a similar proposition, as it bundles three related tools into one:
How does Vite pull this off? Well, instead of targeting a single main.js file as our websiteās entry point, it crawls HTML files to track all JavaScript, styles, and miscellaneous assets you use. This enables Vite to manage the entire build pipeline, including a lightning-quick dev server. ā”ļø
In development, Vite can intelligently decide what assets actually need to refresh when saving changes to a file. Edit a React component only used on your homepage, for example?
Instead of re-bundling your entire site as webpack might, Vite will send just the single React component over to your browser. Itāll even avoid refreshing the page and keep your state variables intact.
This hot module reloading is Viteās secret sauce to a positive developer experience, which brings us to Vitestās core value propositions.
šØ Note: Vitest is still not recommended for production use as of February 2022. Check Vitestās homepage for up-to-date suggestions before using it.
Vitest is a a Vi-testing framework built on top of Vite with an eye for both speed and minimal config. Weāll explore each of these in the following sections.
Vitestās approach to the testing space is similar to Viteās approach on the bundling space: let the tool control your entire environment, top to bottom. Vitest is a replacement for a suite of tools:
This means far less config, dependency mismatching, and performance monitoring for you to manage. Just install vitest and let the magic happen. āØ
Despite Vitestās sweeping value propositions, its test runner APIs are nearly identical to Jest across the board: describe, expect, it.each, mock functions, spies, concurrent flags for parallel tests⦠the gangās all here (full list of APIs)!
In fact, Vitest and Jest are so similar that itās hardly worth the code sample here. I suggest heading to Vitestās playground to see the test runner in action. But for completeness, hereās a simple unit test written with Vitestās APIs:
// example.test.js
import { expect, test } from 'vitest';
test('Math.sqrt()', () => {
expect(Math.sqrt(4)).toBe(2);
expect(Math.sqrt(144)).toBe(12);
expect(Math.sqrt(2)).toBe(Math.SQRT2);
});
If youāre wondering, āWait, why arenāt those test helpers globally available?ā This is just the default. You can make the Vitest package globally available from a configuration file. See the Vitest docs for more information.
If you create this file locally, you can spin up Vitestās watch mode by running npx vitest. You should see a single Math.sqrt() test with three passing assertions.
Simple test cases are fine, but letās explore some more complex use cases.
I created a full-stack web app using React for the frontend and a Netlify serverless function to handle form requests. I then wrote two test files:
You can explore the full GitHub repo here š
Note these each use a combination of not-so-stock tools: TypeScript, ESM for server and client-side logic, and JSX for the integration test. This should cover a spectrum of popular JavaScript use cases in a single project.
Letās discuss the speed and config improvements using Jest + Babel as a baseline.
TL;DR: Vitest is much easier to configure from scratch than Jest and Babel. Using Vitest is almost a no-brainer if you use Vite already. Even if you donāt, thereās a minimal upfront cost to replicate your Babel build process in a Vite config. Still, if you want your config to be 100% identical to your web appās, you might lean toward using Jest to piggyback on config.
Alright, letās talk config. I tried to use the most popular test suite recommendations as a frame of reference: Jest for test utilities and Babel plugins to transpile what Jest doesnāt understand. I also avoided using Jestās āexperimentalā flag for ESM because itās rockier to use at this moment and may have performance implications.
Also, weāre configuring our test suite without considering the app itself. You might have a better time configuring Jest if your website already has a Babel and webpack config (say, CRA). Letās ignore this for the sake of comparison, though.
Here are all the dev dependencies needed to get our tests running from absolute zero:
{
"devDependencies": {
// babel presets for ESM, typescript, and React
"babel-jest": "^27.5.0",
"@babel/core": "^7.17.0",
"@babel/preset-env": "^7.16.11",
"@babel/preset-react": "^7.16.7",
"@babel/preset-typescript": "^7.16.7",
// Jest types for global "describe," "it," etc
"@types/jest": "^27.4.0",
// Helper to stub out CSS modules when present
// per Jest docs recommendation
// https://jestjs.io/docs/webpack#mocking-css-modules
"identity-obj-proxy": "^3.0.0",
"jest": "^27.5.0",
"typescript": "^4.4.4"
}
}
Thatās nine dependencies total. Despite using this combo of tools for years, it took nearly an hour of sifting through out-of-date packages and Stack Overflow posts to get here!
Stubbing out CSS modules was particularly thorny. Yes, your mileage will vary here, but I want to note this sticking point for newer devs, especially.
Now, letās see our dependencies for Vitest:
{
"devDependencies": {
"@testing-library/react": "^12.1.2",
"typescript": "^4.4.4",
"vitest": "^0.2.7",
// optional plugin - auto-inject "React" import when it's missing
"@vitejs/plugin-react": "^1.0.7",
}
}
We just went from using nine dependencies to four ā three, excluding the optional React plugin. We also got it working on the first try from reading Vitestās docs.
Now, if youāre thinking, āWell sure, but how much config did you have to write,ā donāt worry. It gets better.
First, letās see the necessary config for Jest plus Babel. Weāll need some Jest config to stub out CSS module imports:
// jest.config.js
module.exports = {
coverageProvider: "v8",
moduleNameMapper: {
// stub out CSS imports per Jest's recommendation
"\\.(css)$": "identity-obj-proxy",
},
};
As well as a few Babel presets for React and TypeScript:
// babel.config.js
module.exports = {
presets: [
['@babel/preset-env', {targets: {node: 'current'}}],
['@babel/preset-react', {
"runtime": "automatic"
}],
'@babel/preset-typescript',
],
};
Now, letās see the Vitest config. Because Vitest rolls up the testing and code bundling into a single tool, we only need one config file:
// vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
})
Look, thereās no config for TypeScript, CSS modules, environment presets, or the like! Thatās because Vite handles this out of the box with sensible defaults that we donāt need to tweak. Whatās more, because Vitest simply extends Viteās capabilities, thereās zero necessary config for existing Vite projects.
Iāll add a disclaimer to this section before we begin: Vitest is still in its early days right now, so there are few benchmarks to speak of beyond this initial exploration from Matti Bar-Zeev. To summarize the findings:
watch mode is much faster than the Jest equivalentMy findings were pretty dang similar.
I will say this is purely anecdotal evidence. These results are based on my local machineās performance and will likely vary for those cloning the repo and trying at home. I recommend skeptical early adopters try for themselves, but here are my findings:
watch mode ā about 1s per run versus Vitestās 1.88s using vitest run.Letās explore why this might be the case.
watch mode so quick?I think Anthony Fuās Twitter post says it best:
Just like how Vite works in the browser, Vitest also knows the graph of your modules, which makes it able to do smart detection and only rerun the related tests. Feels almost like HMR but for tests š
This is the greatest advantage of bundling your dev environment into a single tool. Because Vitest knows every module your app depends on, it can smartly decide which tests should rerun on a file change. This is especially useful in our integration test example.
Whenever we edit our Form.tsx, Vitest can quickly discover which tests rely on this file, re-process it in a flash, and only rerun the related tests. By comparison, I couldnāt get Jest to rerun at all while editing test file dependencies like this.
Okay, letās address that performance hit outside of watch mode. This is a known issue in the Vitest community that stems from a core difference over Jest: Vitest is ESM-first, while Jest is based on the older CommonJS standard you may know from Node.
In other words, you can use import x from 'path' instead of const x = require('path') out of the box.
This is a huge win for modern developer tooling. As more and more modules are dropping CommonJS support, itās crucial that our dev tools stay with the times.
However, this new ESM mindset forces Vitest to use a different test running strategy. To summarize:
This isolation means more time spent spinning up your test suites. Sadly, this has performance implications on small projects and at scale.
Note: you can disable this isolation from their CLI. Youāll need to be extra careful about global state shared between tests, but it should improve performance for most users.
But remember, Vitest is still in its early days. So, Iād avoid using Vitest for production apps right now, per their recommendation. Well, unless minimal config and fast dev servers are enough for you already. š
I hope this post gets you excited for Vitestās future! Itās still in the development phase, so I highly encourage you to check out the Discord community to ask questions, contribute PRs, and watch the performance discussions over time. āSimplifying developer toolingā is a major trend to look out for, and I expect Vitest to only push this vision further.
Thereās no doubt that frontends are getting more complex. As you add new JavaScript libraries and other dependencies to your app, youāll need more visibility to ensure your users donāt run into unknown issues.
LogRocket is a frontend application monitoring solution that lets you replay JavaScript errors as if they happened in your own browser so you can react to bugs more effectively.
LogRocket works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your appās performance, reporting metrics like client CPU load, client memory usage, and more.
Build confidently ā start monitoring for free.

Learn how to build and install three Claude Code mods to monitor usage, protect secrets, and track changes.

I tested Jev against popular LLMs to compare speed, cost, and accuracy on real bank support messages.

Is react-markdown slowing down your app? We benchmarked three top streaming Markdown renderers to find the fastest, most efficient alternative for React.

Learn how coding agents streamline TDD with automated tests, quality guardrails, and mutation testing to catch bugs and build reliable software.
Would you be interested in joining LogRocket's developer community?
Join LogRocketās Content Advisory Board. Youāll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up now