The Angular CLI uses Vitest as the default unit test runner for new projects. This guide provides instructions for migrating an existing project from Karma and Jasmine to Vitest.
IMPORTANT: Migrating an existing project to Vitest is considered experimental. This process also requires the use of the application build system, which is the default for all newly created projects.
Manual migration steps
Before using the automated refactoring schematic, you must manually update your project to use the Vitest test runner.
1. Install dependencies
Install vitest and a DOM emulation library. While browser testing is still possible (see step 5), Vitest uses a DOM emulation library by default to simulate a browser environment within Node.js for faster test execution. The CLI automatically detects and uses happy-dom if it's installed; otherwise, it falls back to jsdom. You must have one of these packages installed.
npm
npm install --save-dev vitest jsdom
yarn
yarn add --dev vitest jsdom
pnpm
pnpm add -D vitest jsdom
bun
bun add --dev vitest jsdom
2. Update angular.json
In your angular.json file, find the test target for your project and change the builder to @angular/build:unit-test.
{ "projects": { "your-project-name": { "architect": { "test": { "builder": "@angular/build:unit-test" } } } }}
The unit-test builder defaults to "tsConfig": "tsconfig.spec.json" and "buildTarget": "::development". You can explicitly set these options if your project requires different values. For example, if the development build configuration is missing or you need different options for testing, you can create and use a testing or similarly named build configuration for buildTarget.
The @angular/build:karma builder previously allowed build options (like polyfills, assets, or styles) to be configured directly within the test target. The new @angular/build:unit-test builder does not support this. If your test-specific build options differ from your existing development build configuration, you must move them to a dedicated build target configuration. If your test build options already match your development build configuration, no action is needed.
3. Handle custom karma.conf.js configurations
Custom configurations in karma.conf.js are not automatically migrated. Before deleting your karma.conf.js file, review it for any custom settings that need to be migrated.
Many Karma options have equivalents in Vitest that can be set in a custom Vitest configuration file (e.g., vitest.config.ts) and linked to your angular.json via the runnerConfig option.
Common migration paths include:
- Reporters: Karma reporters must be replaced with Vitest-compatible reporters. These can often be configured directly in your
angular.jsonunder thetest.options.reportersproperty. For more advanced configurations, use a customvitest.config.tsfile. - Plugins: Karma plugins may have Vitest equivalents that you will need to find and install. Note that code coverage is a first-class feature in the Angular CLI and can be enabled with
ng test --coverage. - Custom Browser Launchers: These are replaced by the
browsersoption inangular.jsonand the installation of a browser provider like@vitest/browser-playwright.
For other settings, consult the official Vitest documentation.
4. Remove Karma and test.ts files
You can now delete karma.conf.js and src/test.ts from your project and uninstall the Karma-related packages. The following commands are based on the packages installed in a new Angular CLI project; your project may have other Karma-related packages to remove.
npm
npm uninstall karma karma-chrome-launcher karma-coverage karma-jasmine karma-jasmine-html-reporter
yarn
yarn remove karma karma-chrome-launcher karma-coverage karma-jasmine karma-jasmine-html-reporter
pnpm
pnpm remove karma karma-chrome-launcher karma-coverage karma-jasmine karma-jasmine-html-reporter
bun
bun remove karma karma-chrome-launcher karma-coverage karma-jasmine karma-jasmine-html-reporter
5. Configure browser mode (optional)
If you need to run tests in a real browser, you must install a browser provider and configure your angular.json.
Install a browser provider:
Choose one of the following browser providers based on your needs:
- Playwright:
@vitest/browser-playwrightfor Chromium, Firefox, and WebKit. - WebdriverIO:
@vitest/browser-webdriveriofor Chrome, Firefox, Safari, and Edge. - Preview:
@vitest/browser-previewfor Webcontainer environments (like StackBlitz).
npm
npm install --save-dev @vitest/browser-playwright
yarn
yarn add --dev @vitest/browser-playwright
pnpm
pnpm add -D @vitest/browser-playwright
bun
bun add --dev @vitest/browser-playwright
Update angular.json for browser mode:
Add the browsers option to your test target's options. The browser name depends on the provider you installed (e.g., chromium for Playwright, chrome for WebdriverIO).
{ "projects": { "your-project-name": { "architect": { "test": { "builder": "@angular/build:unit-test", "options": { "browsers": ["chromium"] } } } } }}
Headless mode is enabled automatically if the CI environment variable is set or if a browser name includes "Headless" (e.g., ChromeHeadless). Otherwise, tests will run in a headed browser.
Automated test refactoring with schematics
IMPORTANT: The refactor-jasmine-vitest schematic is experimental and may not cover all possible test patterns. Always review the changes made by the schematic.
The Angular CLI provides the refactor-jasmine-vitest schematic to automatically refactor your Jasmine tests to use Vitest.
Overview
The schematic automates the following transformations in your test files (.spec.ts):
- Converts
fitandfdescribetoit.onlyanddescribe.only. - Converts
xitandxdescribetoit.skipanddescribe.skip. - Converts
spyOncalls to the equivalentvi.spyOn. - Replaces
jasmine.objectContainingwithexpect.objectContaining. - Replaces
jasmine.anywithexpect.any. - Replaces
jasmine.createSpywithvi.fn. - Updates
beforeAll,beforeEach,afterAll, andafterEachto their Vitest equivalents. - Converts
fail()to Vitest'svi.fail(). - Adjusts expectations to match Vitest APIs
- Adds TODO comments for code that cannot be automatically converted
The schematic does not perform the following actions:
- It does not install
vitestor other related dependencies. - It does not change your
angular.jsonto use the Vitest builder or migrate any build options (likepolyfillsorstyles) from thetesttarget. - It does not remove
karma.conf.jsortest.tsfiles. - It does not handle complex or nested spy scenarios, which may require manual refactoring.
Running the schematic
Once your project is configured for Vitest, you can run the schematic to refactor your test files.
To refactor all test files in your default project, run:
ng g @schematics/angular:refactor-jasmine-vitest
Options
You can use the following options to customize the schematic's behavior:
| Option | Description |
|---|---|
--project <name> |
Specify the project to refactor in a multi-project workspace. Example: --project=my-lib |
--include <path> |
Refactor only a specific file or directory. Example: --include=src/app/app.component.spec.ts |
--file-suffix <suffix> |
Specify a different file suffix for test files. Example: --file-suffix=.test.ts |
--add-imports |
Add explicit vitest imports if you have disabled globals in your Vitest configuration. |
--verbose |
See detailed logging of all transformations applied. |
After migrating
After the schematic completes, it's a good practice to:
- Run your tests: Execute
ng testto ensure that all tests still pass after the refactoring. - Review the changes: Look over the changes made by the schematic, paying close attention to any complex tests, especially those with intricate spies or mocks, as they may require further manual adjustments.
The ng test command builds the application in watch mode and launches the configured runner. Watch mode is enabled by default when using an interactive terminal and not running on CI.
Configuration
The Angular CLI takes care of the Vitest configuration for you, constructing the full configuration in memory based on options in angular.json.
Custom Vitest configuration
IMPORTANT: While using a custom configuration enables advanced options, the Angular team does not provide direct support for the specific contents of the configuration file or for any third-party plugins used within it. The CLI will also override certain properties (test.projects, test.include) to ensure proper operation.
You can provide a custom Vitest configuration file to override the default settings. For a full list of available options, see the official Vitest documentation.
1. Direct path:
Provide a direct path to a Vitest configuration file in your angular.json:
{ "projects": { "your-project-name": { "architect": { "test": { "builder": "@angular/build:unit-test", "options": { "runnerConfig": "vitest.config.ts" } } } } }}
2. Automatic search for base configuration:
If you set runnerConfig to true, the builder will automatically search for a shared vitest-base.config.* file in your project and workspace roots.
Bug reports
Report issues and feature requests on GitHub.
Please provide a minimal reproduction where possible to aid the team in addressing issues.