Skip to main content
Codemods are powerful automation tools, but they’re not always the best solution. This guide helps you decide when to use codemods versus manual migration.

When Codemods Excel

Codemods are ideal for transformations that are:

Mechanical and Repetitive

If the change follows a consistent pattern across many files, codemods save hours of manual work. Perfect for codemods:
Not ideal for codemods:

Syntactically Deterministic

The transformation can be determined purely from the code structure without external context.
Codemods work best when the “before” and “after” states are clear and unambiguous from the code alone.
Perfect for codemods:
Not ideal for codemods:

High-Volume Changes

The more locations need changing, the more valuable automation becomes.
1

1-5 occurrences

Manual migration is usually faster than writing a codemod
2

5-20 occurrences

Consider codemods if the pattern is very consistent
3

20+ occurrences

Codemods are almost always worth it
4

Multiple repositories

Codemods are essential - impossible to do manually at scale

Common Use Cases

1. Deprecation Migrations

Replacing deprecated APIs with their modern equivalents. Example: util.is* to native checks
Why codemods work well:
  • Pattern is consistent across all usages
  • No semantic changes to behavior
  • High volume in typical codebases
  • Simple 1:1 replacement mapping

2. Import/Require Modernization

Example: CommonJS to ESM
Why codemods work well:
  • Syntactic transformation with clear rules
  • Can handle various destructuring patterns
  • Large-scale impact across entire codebase

3. API Signature Changes

Example: Updated function signatures
This type of transformation requires careful testing because the semantics change (error-first callback vs boolean callback).

4. Configuration Updates

Example: package.json script modifications
Why codemods work well:
  • JSON is highly structured
  • Can use AST-based package.json utilities
  • Consistent patterns across projects
See the package.json utilities for examples.

5. Node.js Version Upgrades

Handling breaking changes when upgrading Node.js versions. Example: Buffer constructor deprecation
Why codemods work well:
  • Official Node.js guidance is clear
  • Transformation rules are well-defined
  • Affects many projects upgrading Node.js
  • High risk of missing instances manually

When to Avoid Codemods

Complex Business Logic

If the transformation requires understanding of:
  • Domain-specific requirements
  • Business rules and edge cases
  • User intent beyond code structure
Example:

Rare or Unique Patterns

If your codebase has unique patterns not shared with other projects:
  • One-off refactorings specific to your architecture
  • Custom framework migrations
  • Project-specific design pattern changes
For one-off refactorings, use search-and-replace with regular expressions or your IDE’s refactoring tools.

Semantic Changes Requiring Analysis

When the transformation changes behavior in ways that need validation:

Small Codebases

If you only have a few files to change, manual migration is often faster:
  • Writing a codemod: 2-4 hours
  • Testing thoroughly: 1-2 hours
  • Manual changes + review: 30 minutes for small projects

Performance-Critical Code

When optimizations matter more than automation:

Hybrid Approach: Codemods + Manual Review

Many successful migrations use a combined strategy:
1

Automate the mechanical parts

Use codemods for straightforward 1:1 replacements
2

Flag edge cases

Have codemods add TODO comments or skip uncertain transformations
3

Manual review and cleanup

Developers review changes and handle flagged cases
4

Test thoroughly

Run full test suite to catch any issues
Example: Conservative codemod

Decision Framework

Use this checklist to decide:
If you answered “Yes” to 4+ questions in the codemod column, automation is likely worth it.

Real-World Examples

✅ Great Codemod Candidate: tmpDir to tmpdir

Node.js deprecated os.tmpDir() in favor of os.tmpdir(). Why it’s perfect:
  • Simple rename (tmpDir → tmpdir)
  • No semantic changes
  • Easy to verify correctness
  • Affects many projects
  • Zero ambiguity
Codemod benefits:
  • Transforms 100% of cases correctly
  • Saves hours across the ecosystem
  • Zero risk of human error

✅ Good Codemod Candidate: http.OutgoingMessage._headers

Private property _headers became getHeaders() method. Why it works:
  • Consistent pattern: obj._headersobj.getHeaders()
  • Property access becomes method call
  • Mostly deterministic transformation
Challenges:
  • Need to handle cases like const h = obj._headers;
  • Codemod flags complex cases for manual review

❌ Poor Codemod Candidate: Express 4 to 5

Migrating Express.js across major versions. Why it’s difficult:
  • Many breaking changes with different patterns
  • Middleware signatures changed
  • Router behavior changed
  • Requires understanding of request/response flow
  • Project-specific middleware needs custom handling
Better approach:
  • Use official migration guide
  • Manual migration with careful testing
  • Focus automation on simple renames only

Getting Started

Ready to use codemods? Start here:

How Codemods Work

Learn the technical foundation of AST transformations

Safety Best Practices

Run codemods safely with version control and testing

Contributing Codemods

If you identify a good codemod candidate for the Node.js ecosystem:
  1. Check the Codemod Registry to see if it exists
  2. Review the Contributing Guide
  3. Start with the codemod structure and testing framework
  4. Share with the community!
The best codemods solve problems that many developers face. If you need it, others probably do too.