> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/nodejs/userland-migrations/llms.txt
> Use this file to discover all available pages before exploring further.

# When to Use Codemods

> Understand when automated codemods are the right choice versus manual migration for your Node.js project

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:**

```javascript theme={null}
// Replacing deprecated util.is* methods across 100+ files
util.isArray(value)     → Array.isArray(value)
util.isString(value)    → typeof value === 'string'
util.isFunction(value)  → typeof value === 'function'
```

**Not ideal for codemods:**

```javascript theme={null}
// Complex refactoring requiring business logic understanding
function processUser(user) {
  // Needs context-aware restructuring of data flow
  // Different in each file based on use case
}
```

### Syntactically Deterministic

The transformation can be determined purely from the code structure without external context.

<Note>
  Codemods work best when the "before" and "after" states are clear and unambiguous from the code alone.
</Note>

**Perfect for codemods:**

```javascript theme={null}
// API renaming - always transforms the same way
fs.rmdir(path, { recursive: true })  →  fs.rm(path, { recursive: true })
```

**Not ideal for codemods:**

```javascript theme={null}
// Requires understanding of runtime behavior
const config = loadConfig(); // What's in config?
if (config.useNewAPI) {      // Runtime conditional
  // Should this be transformed?
}
```

### High-Volume Changes

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

<Steps>
  <Step title="1-5 occurrences">
    Manual migration is usually faster than writing a codemod
  </Step>

  <Step title="5-20 occurrences">
    Consider codemods if the pattern is very consistent
  </Step>

  <Step title="20+ occurrences">
    Codemods are almost always worth it
  </Step>

  <Step title="Multiple repositories">
    Codemods are essential - impossible to do manually at scale
  </Step>
</Steps>

## Common Use Cases

### 1. Deprecation Migrations

Replacing deprecated APIs with their modern equivalents.

**Example: `util.is*` to native checks**

```javascript theme={null}
// Before
const util = require('util');
if (util.isArray(data)) {
  // ...
}

// After
if (Array.isArray(data)) {
  // ...
}
```

**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**

```javascript theme={null}
// Before
const fs = require('fs');
const { readFile } = require('fs/promises');

// After
import fs from 'fs';
import { readFile } from 'fs/promises';
```

**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**

```javascript theme={null}
// Before
fs.exists(path, (exists) => {
  if (exists) handleFile();
});

// After
fs.access(path, (err) => {
  if (!err) handleFile();
});
```

<Warning>
  This type of transformation requires careful testing because the semantics change (error-first callback vs boolean callback).
</Warning>

### 4. Configuration Updates

**Example: package.json script modifications**

```json theme={null}
// Before
{
  "scripts": {
    "test": "node --experimental-modules test.js"
  }
}

// After
{
  "scripts": {
    "test": "node test.js"
  }
}
```

**Why codemods work well:**

* JSON is highly structured
* Can use AST-based package.json utilities
* Consistent patterns across projects

See the [package.json utilities](/api/package-json-utilities) for examples.

### 5. Node.js Version Upgrades

Handling breaking changes when upgrading Node.js versions.

**Example: Buffer constructor deprecation**

```javascript theme={null}
// Before (deprecated in Node.js 10)
new Buffer(10);
new Buffer([1, 2, 3]);
new Buffer('text');

// After
Buffer.alloc(10);
Buffer.from([1, 2, 3]);
Buffer.from('text');
```

**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:**

```javascript theme={null}
// Refactoring authentication flow - too context-dependent
function authenticate(user) {
  // Each project has different requirements
  // Needs human judgment on security implications
}
```

### 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

<Tip>
  For one-off refactorings, use search-and-replace with regular expressions or your IDE's refactoring tools.
</Tip>

### Semantic Changes Requiring Analysis

When the transformation changes behavior in ways that need validation:

```javascript theme={null}
// Changing error handling strategy
try {
  await riskyOperation();
} catch (err) {
  // Different error handling needed based on context
  // Humans must decide the right approach
}
```

### 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:

```javascript theme={null}
// Hot path requiring careful performance tuning
for (let i = 0; i < million; i++) {
  // Each optimization needs manual review
  // Automated transformation might miss perf implications
}
```

## Hybrid Approach: Codemods + Manual Review

Many successful migrations use a combined strategy:

<Steps>
  <Step title="Automate the mechanical parts">
    Use codemods for straightforward 1:1 replacements
  </Step>

  <Step title="Flag edge cases">
    Have codemods add TODO comments or skip uncertain transformations
  </Step>

  <Step title="Manual review and cleanup">
    Developers review changes and handle flagged cases
  </Step>

  <Step title="Test thoroughly">
    Run full test suite to catch any issues
  </Step>
</Steps>

**Example: Conservative codemod**

```typescript theme={null}
// Codemod can transform simple cases
util.isArray(x) → Array.isArray(x)

// But adds TODO for complex ones
const check = someCondition ? util.isArray : util.isObject;
// → /* TODO: Review this util.is* usage - codemod skipped */
```

## Decision Framework

Use this checklist to decide:

| Question                                      | Yes → Codemod | No → Manual |
| --------------------------------------------- | ------------- | ----------- |
| Are there 20+ locations to change?            | ✅             | ❌           |
| Is the pattern consistent across files?       | ✅             | ❌           |
| Can you define clear transformation rules?    | ✅             | ❌           |
| Is this a common Node.js upgrade scenario?    | ✅             | ❌           |
| Does it require business logic understanding? | ❌             | ✅           |
| Is the change purely syntactic?               | ✅             | ❌           |
| Will this help other projects too?            | ✅             | Maybe       |

<Note>
  If you answered "Yes" to 4+ questions in the codemod column, automation is likely worth it.
</Note>

## 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._headers` → `obj.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:

<CardGroup cols={2}>
  <Card title="How Codemods Work" href="/concepts/how-codemods-work">
    Learn the technical foundation of AST transformations
  </Card>

  <Card title="Safety Best Practices" href="/concepts/safety-best-practices">
    Run codemods safely with version control and testing
  </Card>
</CardGroup>

## Contributing Codemods

If you identify a good codemod candidate for the Node.js ecosystem:

1. Check the [Codemod Registry](https://codemod.link/nodejs-official) to see if it exists
2. Review the [Contributing Guide](/contributing/creating-recipes)
3. Start with the codemod structure and testing framework
4. Share with the community!

<Tip>
  The best codemods solve problems that many developers face. If you need it, others probably do too.
</Tip>
