Nuxt Test Utils

Official testing toolkit for Nuxt apps, with Suspense-aware component mounting and real e2e fixtures.

Library
npm
v4.2.0
438stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
85/100Excellent
Development Activity100
Maintenance84
Community68
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
79/100Good
Architecture82
Code Quality85
Innovation80
Learning Curve70

Nuxt Test Utils (@nuxt/test-utils) is the Nuxt team’s own answer to testing Nuxt applications end to end and at the component level. Rather than asking developers to mock away Nuxt’s runtime — auto-imports, composables like useAsyncData, and plugin injections — it provides mountSuspended and renderSuspended wrappers around @vue/test-utils and @testing-library/vue that drive components through Vue’s Suspense boundary so async setup resolves exactly as it would in the running app.

For broader end-to-end coverage, the library’s e2e layer can build or dev-start a real fixture Nuxt application and its Nitro server, letting tests assert against actual HTTP responses and page output rather than a simulated environment. It integrates with Vitest, Jest, Cucumber, and Bun through small runner-specific setup modules, and ships a companion Playwright integration and browser-mode testing environment for full-browser assertions, all installed as a single Nuxt module that also handles test-time app-config inlining and auto-import mocking.

What You Get

  • Suspense-aware component mounting/rendering helpers (mountSuspended, renderSuspended) that work with your Nuxt app’s real plugins and composables.
  • An e2e testing layer that can boot a real fixture Nuxt app and Nitro server, with setup modules for Vitest, Jest, Cucumber, and Bun.
  • A bundled Nuxt module that inlines app config for test builds and enables auto-import mocking.
  • Playwright and browser-mode integrations for full end-to-end assertions in a real browser.

Common Use Cases

  • Writing Vitest unit tests for Nuxt components that depend on composables, plugins, or auto-imports.
  • Running end-to-end tests against a real built or dev-mode Nuxt app and its API routes.
  • Verifying a Nuxt module’s install-time hooks and generated output against a real Nuxt build.

Under The Hood

Architecture The package is organized as a set of composable entrypoints (e2e.ts, config.ts, module.ts, runtime-utils/index.ts, playwright.ts, vitest-environment.ts, browser/index.ts) each exported as a separate subpath via package.json exports, so consumers only pull in the pieces relevant to their test runner. The e2e layer (src/e2e/) builds a per-suite TestContext (context.ts) that setup files for vitest/jest/cucumber/bun (src/e2e/setup/) populate before tests run, then nuxt.ts resolves the fixture app’s root directory, builds or dev-starts it via @nuxt/kit’s loadNuxt/buildNuxt, and server.ts/run.ts spin up an actual Nitro server process for e2e assertions against real HTTP responses. Runtime-side, runtime-utils/mount.ts and render.ts wrap @vue/test-utils’s mount and @testing-library/vue’s render with a wrapperSuspended helper (utils/suspended.ts) that clones the target component and awaits Vue’s Suspense boundary so async setup() and Nuxt plugin injections resolve before assertions run. The Nuxt module (module.ts, defineNuxtModule) ties runtime and build-time together: it registers a Vite plugin, patches the generated paths.mjs app-config template so tests don’t need a live runtime-config request, and wires an install wizard for first-time setup.

Tech Stack Written entirely in TypeScript under a pnpm workspace, built with tsdown and typed against Nuxt’s own @nuxt/kit/@nuxt/schema. Core dependencies include defu/c12 for config merging and dotenv loading, h3/nitropack for the in-process test server, local-pkg/exsolve for resolving the host project’s Nuxt install, and unplugin for the shared Vite plugin layer; peer dependencies cover the pluggable test-runner integrations — Vitest as the primary runner, @vue/test-utils and @testing-library/vue for component mounting, @playwright/test/playwright-core for browser e2e, and optional @jest/globals/@cucumber/cucumber for teams on other runners. Linting runs through @nuxt/eslint-config, and CI runs type-checking, unit tests, and example-app tests across a matrix of real example apps rather than mocked fixtures.

Code Quality Tests live under test/unit (config, resolve-config, mock-transform, server specs plus snapshots) and test/types for compile-time type assertions, run via Vitest and a separate vue-tsc typecheck pass. A test:examples script additionally runs the real example apps’ own test suites as an end-to-end smoke test of the library itself — an unusually thorough self-hosting test strategy. TypeScript is used throughout with exported type declarations per subpath entrypoint, knip catches unused exports and dependencies, and ESLint plus dedicated CI workflows enforce style. Error handling favors explicit thrown errors with actionable messages over silent fallbacks.

API Design The standout design choice is mountSuspended/renderSuspended — rather than requiring a full browser or JSDOM app bootstrap, they clone the target component into a throwaway host component and drive it through Vue’s Suspense boundary so a component’s real Nuxt-injected async setup resolves exactly as it would in the app, without hand-mocking those injections. Combined with the Nuxt module’s ability to inline app config into the build so tests don’t need a live runtime-config server request, and a per-subpath exports map that lets a project pull in only the pieces its chosen runner needs, the library offers a notably ergonomic, low-boilerplate path from installing the module to writing a spec file — a pattern generic component-testing libraries can’t offer because they aren’t coupled to one framework’s build pipeline.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search