Speeding up TypeScript Jest Tests: ts-jest VS vitest VS @swc/jest

Recently on my project Terra Draw I took a look at different ways to try and speed up the unit test suite. The test suite wasn't slow, per se, but there are some obvious benefits to making the test suites faster.

In general, faster running unit tests can provide several benefits for developers working on open source projects (and beyond!). Firstly, it allows for faster feedback on code changes, which can improve developer productivity and allow for quicker shipping of new features. We can also see improvements on CI, which can reduce CI job times, potentially saving money and allowing faster deployments of new features over time.

On Terra Draw, there are 442 unit tests that get run. We currently use ts-jest with the default preset configuration. The first thing I attempted is turning off the diagnostics settings for ts-jest, which in theory disables type checking, but it didn't seem to have noticeable impact on the performance of running the test suite.

I then attempted to try using @swc/jest which I found provided a very nice performance boost. The change was reasonably simple, just moving away from:

{
"preset": "ts-jest"
}

To:

{
"transform": {
"^.+\\.(t|j)sx?$": "@swc/jest"
},
"setupFilesAfterEnv": ["<rootDir>/src/test/jest.matchers.ts"]
}

As a final comparison, I gave vitest a try. Installing vitest was simple enough, simply adding it via npm install --save-dev.

I then created a new npm script: "test:vitest": "vitest --globals". Vitest required some additional changes, as it is not a complete drop in replacement for Jest even though the APIs are the same. It required using the --globals flag to support describe, it, expect etc and also updating the code from using the jest imports to vi (i.e.jest.fn() becomes vi.fn()). Upon doing this I was able to ascertain that vitest appeared to be faster than ts-jest but slower than using @swc/jest in this instance.

Here are the overall results:

ts-jest vs vitest vs swc-jest

The comparison of the three libraries: ts-jest, vitest, and swc/jest, shows that the library swc/jest was the fastest in this scenario, with an average running time of 1.99 milliseconds. It is followed by vitest with an average running time of 4.9 milliseconds and ts-jest with an average running time of 10.36 milliseconds. This indicates that swc/jest is significantly faster than ts-jest and in this instance faster than vitest. I feel swc/jest may be a better choice for projects with a large number of tests or those that require fast feedback on code changes.

It is important to note that these were just using the 'default' settings for these libraries. There may be ways I am unaware of for fine tuning the performance of these tests. It is also important to note that I did not test the watch modes, which may provide a very different story as things like caching can come into play.

Published