Since Angular 16, we've got native support for Jest! It's experimental, but that didn't stop me. I took it for a test ride.
TL;DR: Angular's native Jest integration works surprisingly well. However, it's a technology preview, so several limitations stop me from adopting it. For example, it doesn't support multi-projects, and there is no support for Visual Studio Code.
Why do we need native support?
There are a couple of community projects adding Jest support to Angular. For example, there's the "Just Jeb" project. Another popular option is using Nx, especially if you're using a monorepo. Another option is configuring Jest manually.
Until recently, the community projects and the manual configuration did their job without problems. Then Angular migrated to the ESM module system.
Suddenly, it becomes evident that Jest doesn't use the Angular compiler. Instead, it compiles the source code with help from the
jest-preset-angular/setup-jest plugin. In a nutshell, this plugin adds the same functionality that the Angular compiler adds to the TypeScript compiler. But the plugin can't change the module system used by Jest. It converts the ESM modules to the CommonJS format. So you end up with double compilation plus a time-consuming conversion between module systems. Rainer Hahnekamp has an article covering the problem in depth.
Native support for Jest aims to fix both problems.
Activating the native support of Jest
It's time to get our feet wet. All you have to do is to replace the Karma builder with the Jest builder. Open the
angular.json file and replace the
test section with the following:
Next, you'll have to install Jest and the Angular builder for Jest:npm install jest @types/jest jest-environment-jsdom --save-dev
Now it's time to update your
tsconfig.*.json files. Locate the
compilerOptions/types section and replace
That's it. Optionally, you can remove Karma and Jasmine from your project, but I don't think that's mandatory. You can now run your tests with
What about fine-tuning Jest?
I haven't mentioned any configuration files like
setup-jest.ts yet, and that's no coincidence. Angular aims to be a carefree package. Plus, the Angular team needs a certain level of control. So they decided not to expose the Jest configuration. Granted, at the time of writing, the GitHub ticket is still open, so maybe that's subject to change, but it'd match the general philosophy of Angular.
Running the tests
If everything goes according to plan, this is a bit anticlimactic. You can run the tests with
ng test, and the tests run unless you've got an advanced project.
Most of you (including me) have a more advanced project, so you'll have to adjust a thing or two, but if you're familiar with Jest, you'll manage. If you aren't, ask ChatGPT, Bard, or GitHub Copilot. They'll help you. Please anonymize your code before sending it to the server. Otherwise, you're giving your employer's (or even your) intellectual property to a foreign company for free.
The anticlimactic part is that the tests run without further ado. That's it.
At a second glance, there's no Karma server. There's no annoying browser window popping up. Even better, the tests run faster. You'll love it!
It's time to cover the rough edges. There are quite a few; I'm sure I've missed some. However, I was particularly frustrated by the lack of IDE integration. I've managed to get it working, but only just. Maybe it's more honest to say I've failed, but only by a margin.
Some time ago, I suggested using Orta's Jest plugin. It didn't work out of the box. I think I've found the reason by now, but I suspected the plugin to be incompatible, so I opted for the second-most popular Jest plugin: Jest Runner.
I prefer Jest Runner because of its limited focus: it allows me to run and debug tests with a single click in the IDE - nothing more and nothing less. Orta's plugin is more ambitious.
The long period of trial and error told me that the Jest Runer plugin requires you to add these lines to your
This configuration, in turn, refers to the
setupJest.ts file, so you'll have to add it:
That's it. Now, you can run your tests from your IDE. The plugin adds a "run/debug" line above your tests so you can start or debug your tests with a single click. Hooray!
There's only one little problem: both
ng test and
npm run test are broken.
At the moment, I haven't found a solution. I ended up renaming the
jest section of my
deactivated-jest, renaming it to
jest each time I want to run the tests from the IDE, and renaming it back to
deactivated-jest when I want to run the tests from the command line.
I'm not happy with this solution. But then, it's a technology preview. When I started the test ride, I didn't expect it to be smooth.
What about the "import is not defined" message?
If you run into this method, your module system is configured badly in one of your
tsconfig.json files. I know of two possible reasons:
- If you want to use the IDE integration and you run into this error, activate the
jestsection of your
jest-preset-angularis active, it overrides the module settings of your
- If you encounter this error when running the
ng test,you must configure the module setting in the
tsconfig.jsonfile. If you've got multiple
tsconfig.*.jsonfiles in your project, it's the one you've referred to in the
angular.jsonfile. The correct setting seems to be
This is a short section: The Angular CLI does not support Jest in monorepos. More to the point, monorepos aren't supported in Angular 17. The good news is the Angular team has it on their roadmap.
In the meantime
If you're unhappy with Jasmine and Karma or curious, you don't have to wait until the Angular team delivers. Read my follow-up articles to learn how to configure an Angular monorepo manually or how to do it using the @angular-builders/jest plugin.
Wrapping it up
At the time of writing, Angular's native support for Jest is a technology preview - nothing more and nothing less.
On the plus side, it works surprisingly well, as long as you respect its limitations: there's no IDE support or monorepo support.
My gut feeling tells me the Angular team won't abandon Jest. But that's just my gut feeling, backed by awfully little insight, apart from my experience that Jest is superior. However, whether the Angular team shares my feelings is different story.