Vue Test Utils is the component testing layer for Vue 3
Vue Test Utils for Vue 3
At a glance
- What is it?
- Vue Test Utils is the component testing library for Vue 3, published to npm as @vue/test-utils, and its repository is as much about how the package is built and released as about the API. The build is a rollup pipeline emitting CommonJS, bundler ESM and browser bundles, the tests run on vitest with a separate vue-tsc type test suite, the documentation is a VitePress site with a translation workflow, and releases go out through npm trusted publishing with an approval gate that the person pushing the tag cannot satisfy on their own.
- Who is it for?
- Vue Test Utils is the library to reach for if you test Vue components, because it solves the parts of component testing that a generic DOM test framework cannot, and because the package is a normal npm dependency with a documented release process, so a pinned version in your lockfile means something.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the library is for
The project describes itself in one line, component testing utils for Vue 3, and the installation section gives the two commands a project needs:
yarn add @vue/test-utils --dev
npm install @vue/test-utils --save-devThe package name in the metadata is @vue/test-utils, the version is 2.5.1, and the licence is MIT with the author listed as Lachlan Miller. The documentation lives at test-utils.vuejs.org, and the repository carries the source, the tests, a type test directory, the documentation sources and a single example, a TodoApp.vue component with its TodoApp.spec.ts, which is a nice touch for a library because the example is the thing a newcomer will copy. The audience is a Vue team writing component tests, and the library's job is to make the mounting, the props and the emitted events feel like the component rather than like the framework's internals.
The Vue 2 migration is still open
There is a section headed Coming from Vue 2 + Test Utils v1, and it points at the migration guide with a caveat that it is still a work in progress. The instruction to the reader is concrete, if you find a problem or something that does not work that previously did in Vue Test Utils v1, please open an issue. That is a request for the missing tests of the compatibility surface, and it tells you something about the state of the migration that a version number does not. The rest of the repository does not dwell on it, which is consistent with a library that has moved on to Vue 3 while still carrying the people who have not. If you are on Vue 2 today, the v1 line is the relevant one, and if you are planning a move, the open issue list is where the known differences are collected.
Releases are gated, and the gate cannot be self-served
The Releasing section is unusually detailed, and it is a good model for a package with many users. Releases are published to npm from GitHub Actions using npm trusted publishing, and publishing with npm tokens is disabled, so a release requires write access to the vuejs/test-utils repository, the release commit to be on main, package.json to contain the version being released, and approval from a maintainer with access to the npm-publish GitHub environment. To cut a release you push a version tag from main:
git checkout main
git pull
git tag v2.x.y
git push origin v2.x.yPushing a v* tag starts the release workflow, which builds the package, pauses for approval in the npm-publish environment, and then publishes @vue/test-utils to npm after approval. The rule that stands out is that the person who pushed the tag cannot self-approve the publish step, which closes the obvious loophole in a scheme that otherwise lets one account publish to npm.
Three bundles, one package
The package metadata shows the shape of the build, and it is the standard modern layout for a library that has to work in every environment a Vue app might be built by. The main entry is the CommonJS build, dist/vue-test-utils.cjs.js, the module field points at the bundler ESM build, dist/vue-test-utils.esm-bundler.mjs, the types field is dist/src/index.d.ts, and unpkg points at dist/vue-test-utils.browser.js for the browser build. The exports map resolves the types, a node condition, import, require, browser and a default, and the published files are dist, the README and the type declarations. The build itself is a single rollup configuration, rollup.config.ts, invoked both by the build script and by the prepare script, and the files field deliberately excludes the sources so that the type tests and the test files are not shipped to users.
Tests, type tests, and a separate Volar config
The test story is split in a way that says something about the library. The runtime tests are vitest, with a watch mode and a coverage mode, and there is a test:build mode that runs the suite against the built package rather than the sources, which catches packaging mistakes that a source-level test cannot. The type tests are separate, with a tsd script that runs vue-tsc --noEmit against test-dts/tsconfig.tsd.json, so the public types are checked rather than assumed, and there is a tsconfig.volar.json in the tree, which is the Volar configuration used to type the documentation and the examples. The linting has moved away from eslint to oxlint with oxfmt for formatting, and the configuration files .oxlintrc.json and .oxfmtrc.jsonc sit at the root, so the project is on the newer Rust based toolchain for both.
The documentation is a product with its own translation pipeline
The docs directory holds the English markdown files, and translations live in their corresponding language sub-folders, with fr for French at the moment, and the .vitepress sub-folder contains the configuration and theme including the internationalisation information. The commands are published so contributors do not have to learn the tooling, with pnpm docs:dev to start the dev server and pnpm docs:build to build the site, and the translation workflow has its own verbs. pnpm docs:translation:status with an optional language shows the translation status, showing all languages if none is given. pnpm docs:translation:compare compares the docs with the latest checkpoint for that language. And pnpm docs:translation:update updates the checkpoint, which is set by the latest commit hash unless a commit hash is given manually. The guidelines followed are the Vue Ecosystem Translation Guidelines, and the site deploys through netlify.toml.
Where this library stops
Two limits are visible in the repository itself. The first is the Vue 3 boundary, since the package is the Vue 3 line and the Vue 2 story is the v1 line with an unfinished migration guide. The second is the scope of what a component test can assert, which is a property of the library rather than a gap in it, since a test that mounts a component sees the rendered output and the emitted events, not the internals of the component, and the project is careful to keep the public API surface small enough that the type tests and the documentation stay in step. For a team that has outgrown mounting components by hand, the alternative is to test the logic as plain functions and leave the component thin, which is a design decision rather than a tooling one, and this library makes the thin component cheap to test. The development story is minimal, with pnpm install and pnpm test and nothing else, and the tests include the type tests and the build mode, which is the part a consumer will actually feel if a release goes wrong.
Editorial conclusion
Vue Test Utils is the library to reach for if you test Vue components, because it solves the parts of component testing that a generic DOM test framework cannot, and because the package is a normal npm dependency with a documented release process, so a pinned version in your lockfile means something. It is the wrong choice for a project still on Vue 2, where the v1 line applies and the migration guide is explicitly still a work in progress, and it is the wrong tool for logic that belongs in a plain unit test. Before you upgrade from Test Utils v1, read the migration guide and check the open issues, because the project asks you to report anything that used to work and does not.
Frequently asked questions
How do I install Vue Test Utils for Vue 3?
With yarn add @vue/test-utils --dev, or npm install @vue/test-utils --save-dev. The package is published as @vue/test-utils at version 2.5.1 under the MIT licence, and the documentation is at test-utils.vuejs.org.
How are Vue Test Utils releases published?
Releases go to npm from GitHub Actions using npm trusted publishing, with npm tokens disabled. A release needs write access to the repository, the release commit to be on main, package.json to hold the version, and approval from a maintainer with access to the npm-publish environment, and the person who pushed the version tag cannot approve the publish step themselves.
How do I contribute translations to the Vue Test Utils docs?
The English markdown is in docs and translations live in a language sub-folder, with fr for French currently. The tooling is pnpm docs:translation:status, pnpm docs:translation:compare and pnpm docs:translation:update, and the project follows the Vue Ecosystem Translation Guidelines.
What is the difference between Vue Test Utils v1 and v2?
v1 was for Vue 2 and v2 is the Vue 3 line, and the migration guide is described as still a work in progress. The project asks anyone who finds something that worked in v1 and does not work now to open an issue, so the known differences are collected there.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/vuejs-test-utils)Was this useful?