Skip to main content

CODEMOD HYGIENE

codemod-hygiene.md

After a jscodeshift/recast codemod, strip incidental reformatting so the diff shows only the semantic change.

Stark avatarStark

WHAT THIS PATTERN TEACHES

Why AST codemods built on recast preserve formatting for untouched nodes but RE-PRINT touched nodes — so any file with pre-existing format debt gets reformatted beyond the semantic change, inflating the diff and burying the real change. The procedure for separating semantic hunks from reformatting hunks.

WHEN TO USE THIS

Any AST codemod run (jscodeshift, @next/codemod, react-codemod, or a hand-rolled recast transform) over a codebase with pre-existing format debt.

AT A GLANCE

# Hygiene procedure
1. Run the codemod on a clean tree.
2. Separate semantic hunks from reformatting hunks.
3. Revert incidental hunks (git checkout -p), re-apply only the semantic change.
4. OR run the formatter scoped to changed files BEFORE the codemod.

FRAMEWORK IMPLEMENTATIONS

Markdown
# Pattern: Codemod Hygiene (strip incidental reformatting)

When to use: any AST codemod run (jscodeshift, @next/codemod, react-codemod, or
a hand-rolled recast transform) over a codebase with pre-existing format debt.

## The failure mode

AST codemods built on recast preserve formatting for nodes they DON'T touch but
RE-PRINT touched nodes from the AST — so any file with pre-existing format debt
(irregular JSX wrapping, multi-line object style, mixed quotes) gets reformatted
beyond the semantic change, inflating the diff and burying the real change.

## Hygiene procedure

1. Run the codemod on a clean tree.
2. Review the diff and separate semantic hunks from reformatting hunks.
3. For files where reformatting dominates, git checkout -p / revert the
   incidental hunks and re-apply ONLY the semantic change by hand.
4. OR run the project formatter (prettier / eslint --fix) scoped to changed
   files BEFORE the codemod so the codemod's reprint matches existing style,
← All Patterns