Introduction
jscodeshift is Meta's toolkit for writing and running codemods — automated code transformations that modify source files by manipulating abstract syntax trees rather than text. It wraps the recast printer to preserve formatting and provides a chainable API that makes large-scale refactors safe, repeatable, and reviewable.
What jscodeshift Does
- Parses JavaScript and TypeScript files into ASTs using babel or TypeScript parsers
- Provides a jQuery-inspired API for finding, filtering, and replacing AST nodes
- Preserves original formatting and whitespace through the recast pretty-printer
- Runs transforms in parallel across thousands of files using worker processes
- Supports dry-run mode to preview changes before writing them to disk
Architecture Overview
jscodeshift reads source files, parses them into ASTs via configurable parsers (babel, flow, ts, tsx), and passes each AST to a user-defined transform function. The transform uses the Collection API to query and modify nodes. After transformation, recast reprints the modified AST back to source, preserving untouched code exactly as written. A runner coordinates parallel execution across files using Node.js worker threads.
Self-Hosting & Configuration
- Install locally per project:
npm install --save-dev jscodeshift - Write transforms as CommonJS or ES modules exporting a function that receives
(fileInfo, api, options) - Use
--parser babelfor modern JS or--parser tsxfor TypeScript and JSX files - Pass custom options to transforms via
--key=valueflags on the CLI - Configure
.jscodeshift.config.jsfor default parser and extension settings
Key Features
- jQuery-like chainable API:
root.find(j.CallExpression).filter(...).replaceWith(...) - Format-preserving output that only changes lines touched by the transform
- Built-in test utilities for writing unit tests against transform functions
- Parallel file processing for fast execution on large codebases
- Extensible parser support for Flow, TypeScript, and JSX
Comparison with Similar Tools
- ts-morph — TypeScript-specific with compiler API access; jscodeshift works across JS and TS with broader parser support
- Babel plugins — Transform during build; jscodeshift runs as a one-time migration tool
- comby — Language-agnostic structural matching; jscodeshift provides full AST manipulation for JS/TS
- ast-grep — Rust-based with pattern matching syntax; jscodeshift offers a programmatic API for complex logic
- ESLint with --fix — Rule-based fixes; jscodeshift handles arbitrary multi-node transformations
FAQ
Q: When should I use jscodeshift instead of find-and-replace? A: Use jscodeshift when the change depends on code structure — renaming a function only when called with certain arguments, updating import paths conditionally, or restructuring object patterns.
Q: Can I test my codemod before running it?
A: Yes. jscodeshift provides defineTest and defineInlineTest utilities that compare input/output fixture files to verify your transform produces correct results.
Q: Does jscodeshift modify files in place?
A: By default yes. Use --dry to preview changes without writing, or --print to output transformed code to stdout instead.
Q: How do I handle files that fail to parse?
A: jscodeshift logs parse errors and skips those files. You can also specify --ignore-pattern to exclude files that use unsupported syntax.