Automated refactoring with codemods

Codemods are scripts that can automatically transform code from one syntax to another, making it easy to refactor or update large codebases.

What are codemods?

A codemod is a script that can automatically transform code from one syntax to another, such as renaming a variable or moving a function to a different module. They are typically used to refactor code, update APIs, or make other large-scale changes to a codebase. Codemods can save a lot of time and effort when making updates to a codebase, especially when the changes are extensive or would be tedious to do by hand.

They work by using a transformer function to parse the code and apply the desired transformations. The transformer function takes in the code as a string, and it returns the transformed code as a string.

Codemods are typically implemented as scripts that use a tool such as sed or awk to perform search-and-replace operations on the source code. Some popular codemod tools include jscodeshift and codemod-cli, which provide a framework for writing and running codemods.

For example Next.js has a codemod that migrates from Next.js 12 to Next.js 13. It includes a script that can automatically update your codebase to use the new Image Component and implement the new Link behaviour by running npx @next/codemod@latest <transform> <path>.

Writing a codemod

Codemods are typically written in JavaScript, and they use a library called jscodeshift to parse and transform the code. Jscodeshift is a tool that was developed by Facebook for use in their own codebase, and it has since become a popular choice for writing codemods.

Here's an example of a simple codemod that transforms all instances of function foo() to const foo = () =>:

const transform = (code) => {
  return code.replace(/function foo\(\)/g, 'const foo = () =>');

This transformer function uses a regular expression to find all instances of function foo(), and it replaces them with const foo = () =>. The resulting transformed code is then returned as a string. While this example is fairly simple, codemods can be much more complex, using advanced techniques such as AST (abstract syntax tree) manipulation to transform the code in more sophisticated ways.

To use a codemod, you will need to have Node.js and jscodeshift installed on your machine. Once you have these tools set up, you can use the jscodeshift command-line tool to run your codemod script. For example, here's how you might run the above codemod:

jscodeshift -t path/to/codemod.js path/to/codebase

This command will run the codemod script located at path/to/codemod.js on the codebase located at path/to/codebase. The -t flag specifies the path to the codemod script, and the path to the codebase is provided as the final argument.

It's also possible to specify additional options when running a codemod, such as a --dry-run flag to see what changes the codemod would make without actually making them. You can see a full list of available options by running jscodeshift --help.

Things to keep in mind

When writing a codemod, it's important to follow some best practices to ensure that the script is effective and easy to maintain. Here are a few tips for writing a codemod:

  • Test your codemod thoroughly. You're writing a regex that will run over someone's codebase, so it's important to test your codemod on a variety of codebases to make sure it's working correctly. You should also consider writing unit tests for your codemod to ensure that it's reliable and easy to maintain.
  • Document your codemod. It's a good idea to include comments in your codemod explaining what it does and how it works. This will make it easier for others to understand and use your codemod.
  • Make your codemod configurable. It's often useful to make your codemod configurable by allowing the user to specify certain options or settings. This can make it easier to tailor the codemod to the specific needs of a project.
  • Consider using an AST tool. As mentioned earlier, codemods can use AST (abstract syntax tree) manipulation to transform code in more sophisticated ways. Tools like recast and babel can make it easier to work with ASTs and apply more complex transformations.

TL;DR codemods can save heaps of time and effort, and help ensure that updates are applied consistently across a codebase. With the right tools and a bit of practice, you can use codemods to streamline your development workflow and make your projects more efficient.