Run JavaScript and TypeScript codemods at scale with the Moderne Platform

Knut Wannheden
February 22, 2024
JavaScript codemods on the Moderne Platform

Key Takeaways

Moderne’s mission is to enable development teams to automate source-to-source code transformation at scale and with confidence. The Moderne Platform has proven success running OpenRewrite refactoring recipes across large codebases, allowing organizations to migrate, maintain, and secure their code with relative speed and ease. We are also integrating with other refactoring tech like codemods, linters, and formatters that are idiomatic to individual language communities, enabling an all-in-one approach to code maintenance and migrations for enterprises with diverse codebases.

To that end, the Moderne Platform now supports JavaScript and TypeScript codemods, enabling developers to quickly transform and standardize their code at scale across repositories. They can execute whole framework migrations as well as collect data from the code to understand what was changed in the files.

Check out the demo video of running codemods in the Moderne Platform, and read on to learn more about how we can help you manage your JavaScript and TypeScript source code more effectively.

Codemods ready for action in the Moderne Platform

The JavaScript and TypeScript ecosystem has an extensive collection of codemods available today, including upgrades for the Next.js and AngularJS frameworks. Many of these modules either use jscodeshift or come as ESLint plugins. 

Moderne can serve as the hub to bring together all the codemods and ESlint rules so that developers can easily access a broad collection of updates and work on their JavaScript and TypeScript repos at scale. Over 400 codemods recipes have already been curated for the Moderne Platform, encapsulating the best-in-class codemods from across the ecosystem as shown in Figure 1. In addition, because Moderne enables access to multiple repositories, you are able to test and refine code modifications much more quickly as well.

Figure 1. Top-level catalog of JavaScript recipes in the Moderne platform

If you deep dive into the recipes in the Modernize section (Figure 2), you can see the types of upgrades and modernization actions you can take at scale across your JavaScript codebase.

Figure 2. Modernization and migration codemods recipes in the Moderne Platform

Let’s walk through some interesting codemods available within the Moderne Platform.

Improving regex performance and security

You can now clean up your code across multiple repositories, including improving regular expressions. This not only improves page performance but also makes regexes safer against regular expression DOS attacks

Migrating AngularJS framework versions

You can access several framework migration recipes, including the AngularJS upgrade up to version 17.

Modernizing front-end frameworks like React

You can access a selection of recipes to modernize the use of your front-end frameworks like React, aligning them to current best practices. The ‘Applies a codemod to all source files’ recipe enables you to insert the transform to be applied.

How codemods are supported in the Moderne Platform

In the Moderne Platform, we use Lossless Semantic Trees (LSTs) to represent and modify source code. The JavaScript codemods instead typically use an ESTree-compatible AST as produced by the parser. 

To run codemods in the Moderne Platform, we extract the JavaScript source code as text from the LST. Then, we invoke the codemod (encapsulated in a recipe) on the particular repository and related source code as text. 

Recipes are the programs that transform code in the Moderne Platform. Codemods are also programs stored in npm packages with other dependencies. To enable codemods to operate within the context of the Moderne platform, each codemod npm package is self-contained with its options and configurations in a corresponding OpenRewrite recipe of the type ScanningRecipe

Scanning recipes running codemods have three phases:

  1. A scanning phase that collects information while making no new code changes. In this phase, the source file LSTs are printed and saved as files in a working directory of the local file system. Since the recipe could be part of many codemod recipes in the queue, it is in fact only the first recipe that does this step.
  2. A generating phase where new files are created. In this phase, the working directory of the initial recipe in the queue is copied to a new working directory for every recipe in the list, providing source code to work on. Then the codemod is executed by extracting npm packages from the recipe jar onto another working directory.
  3. An editing phase where the recipe makes changes. Every source file being processed will be checked for changes in the recipe’s working directory. If the codemod made any changes to it, a new PlainText source file is returned (which includes the file’s modified contents) and the Moderne system will detect this and be able to attribute the change to the recipe.

Running the codemods recipe produces a diff on the filesystem that the platform captures, and also produces data tables describing what files have been changed. You can then commit to repositories, issue pull requests, etc. After all recipes in a list have been executed, the recipe scheduler deletes all working directories in the local file system for this recipe run.

Figure 3 shows a high-level view of this process.

Figure 3. Three phases of running a codemods-based recipe

Advantages for running codemods in the Moderne Platform

Here are a few advantages for running codemods with the Moderne Platform:

  • The Moderne Platform becomes a centralized hub for accessing a curated set of codemods and ESlint rules for your codebase. Developers can view all the updates in one place and then execute the codemods across multiple repositories. 
  • While the codemod recipes can only use npm packages that are also packaged in the recipe jar, this can offer security advantages within the Moderne Platform because no access to an external npm repository needs to be configured (which can be a challenge in large enterprises).
  • Customizing and testing recipes in the context of the Moderne Platform is fast as you can iteratively run them against large codebases, see results quickly, then fix issues and improve the output. Codemods recipes will also benefit from this infrastructure.

For more information about running codemods at scale across your JavaScript and TypeScript codebases using the Moderne platform, contact us!