Skip to main content

From Mocha to Vitest for 2X Faster Tests

Image

Why bother migrating to Vitest?

Vitest is a modern test runner with improved perfomance and developer experience comapred to many other existing alternatives, which explains its growing popularity.

More specifically, Vitest simplifies configuration, supports TypeScript & ESM, and popular component libraries out of the box. Last but not least, it comes with code coverage analysis, and overall, saving hours of tedious work for developers.

But, the manual migration from Mocha.js to Vitest could take a considerable amount of time, especially when you have a lot of test suites.

What if there were code modification bots that could automate the entire migration process?

Codemod: The code automation platform

Building codemods requires knowledge of abstract syntax trees and compiler internals. The Codemod platform simplifies this by providing tools to build, test, share, and run codemods at any scale:

  • Build: Use Codemod Studio to create and test codemods visually, powered by JSSG (our primary transformation engine built on ast-grep).
  • Share: Publish codemods to the Codemod Registry, making them available to colleagues or the community.
  • Run: Discover and run codemods with a single CLI command.
  • Orchestrate: Use Codemod Workflows to chain multi-step migrations across repositories.

Mocha to Vitest migration with Codemod.com

1. Build the codemod

To build a codemod with Codemod Studio, you provide code snippets showing the before and after states of the transformation. The Studio uses AI to generate the codemod logic, which you can then refine and test interactively.

Imagine we have an existing Mocha.js-compatible test file:

Imagine we have an existing Mocha.js-compatible test file with the following code, which we place in the “before” snippet:

With Vitest, we would write the test file in the following way, which we place in the “after” snippet:

As you can see, in Mocha.js describe, beforeEach, it and afterAll functions exist in the global scope. Additionally, we chose to use the expect function from the chai library explicitly for test assertions. In Vitest, we need to import all of these functions from the vitest package.

Using the Studio's AI assistance, we generated a codemod to handle this transformation. The generated codemod served as a base for the final one called mocha/vitest/migrate-tests. We refined and improved it based on the edge cases we discovered during testing.

We also built a second codemod called mocha/vitest/migrate-configurations that removes all Mocha.js configuration files, drops the library from all package dependencies, and adds Vitest instead.

Both codemods were combined into a recipe called mocha/vitest/recipe which can be discovered, shared, and run from the Codemod Registry.

2. Run the codemod

Run the recipe with a single CLI command:

We ran the recipe over 3 of our own repositories:

  1. codemod-com/filemod
  2. codemod-com/codemod-engine-node
  3. codemod-com/codemod-registry

The first two had a handful of Mocha.js test suites and we migrated them first to spot problems early in the development. Once the codemod was ready and accurate, we merged them into the Codemod Registry. Once codemods are published to the registry, they automatically become accessible to the community via Codemod.com VSCode Extension or the Codemod.com CLI.

And shown below, with the help of our codemod, we automated the bulk of the migration for over 60 test files spread across the entire Codemod Registry monorepo.

We repeated the same steps for the Codemod Engine Node. During testing, we found out Vitest does not transpile TypeScript files if we use them as entry points for thread workers. This functionality used to work with Mocha.js supported by the ts-node/esm dependency. We replaced the path to the TS file with a path to the built ESM files to restore the feature.

Loading tweet...

3. Final tweaks

When migrating the Codemod Registry, we found unhandled cases, like:

  • the usages of the Context type from Mocha.js,
  • the usages of the this variable in test bodies.

We could fix the former problem by putting the existing codemod into the Codemod Studio and asking the AI helper to fix it. With the latter, we fixed the test bodies manually due to the small number of such occurrences.

Since the Codemod.com CLI can execute local codemods, we used it to see if the changes to the codemod resulted in the correct transformation of the codebase in question. This speeded up the development process tremendously.

The impact

With the help of the recipe, we were able to migrate three repositories in a short amount of time. We reused the same code within the recipe for all the projects. Now, other developers may leverage our work as well.

If we were to manually migrate the Codemod Registry alone, we would have to:

  1. delete the 60+ existing Mocha.js configuration files (1 minute for each),
  2. remove Mocha.js and add Vitest dependencies in 60+ package files (1 minute for each),
  3. drop Mocha.js types and put the Vitest import statements in 60+ tests files (2 minutes for each).

It would have taken around 4 hours of mundane work to perform the migration without ensuring we had not introduced any mistakes.

After ensuring the proper quality of the code automation agents, we executed the recipe that transformed over 200 files instantly. We removed all Mocha.js configuration files and thus reduced the complexity of the test suites. Our platform made it all available at the push of a button.

Conclusion

This article walked through migrating from Mocha to Vitest using automated codemods. Key takeaways:

  • Codemods are powerful code transformation tools that can automate tedious migration work at any scale.
  • AI-assisted codemod creation through Codemod Studio and Codemod MCP lets any developer build codemods quickly.
  • Open source: With Codemod's platform, you can automate crucial yet tedious tasks for yourself, your colleagues, and the community.

Start migrating in seconds

Save days of manual work by running automation recipes to automate framework upgrades, right from your CLI, IDE or web app.