Codemod CLI and workflow features are free for local use. For large-scale refactoring across many repos, the Codemod app provides:
Visual parameter configuration - Edit workflow parameters through the UI instead of YAML
Centralized state management - Coordinate migrations with persistent state across repos and teams
Multi-repo orchestration - Run workflows across your entire codebase with progress tracking
Business insights - Track migration progress with custom metrics and dashboards
This is an advanced topic. If you’re just getting started, we recommend using Codemod Studio or Codemod MCP to create your Codemod package with the help of AI.
The folder—called a Codemod package—is the root when you run npx codemod workflow run -w ./my-codemod-package/.
You can combine types in a single package. The scripts/ and rules/ folders are conventional, not required—use any paths and reference them from workflow.yaml.
A Codemod package is a directory containing your workflow.yaml and any scripts, rules, or assets referenced by your workflow.
Codemod package name (unique within scope).Naming rules:/^[a-z0-9-_/]+$/ (lowercase letters, numbers, hyphens, underscores, and / for scope separation only)Not allowed: uppercase letters, dots, commas, spaces, or other special charactersValid examples:
remove-console-logs
@scope/remove-console-logs (using @organization-or-project-scope/name provides better discoverability in the Codemod Registry)
Keyword tags are an optional feature helping developers quickly identify the purpose, scope, and relevance of a codemod. They also enable better search, filtering, and reporting when managing many codemods across frameworks and projects.Example: keywords: ["react", "v18-to-v19", "migration"]
Best practices and conventions
Keep tags concise (1–2 words).
Use lowercase for consistency.
Don’t overload with tags — 2–4 per codemod is ideal.
Prioritize transformation type + framework/library + version (if relevant).
1. Transformation Type TagsConsider these categories when describing why the codemod exists:
upgrade – helps upgrade code to newer versions (encompasses both breaking changes and feature adoption).
You may also consider adding one of the following tags:
breaking-change – adapts code to framework/library breaking API changes.
feature-adoption – helps adoption of new optional or incremental features.
security – addresses known vulnerabilities or unsafe patterns.
cross-migration – replaces one library/framework with another.
i18n – internationalization migrations or improvements.
a11y – accessibility improvements and compliance.
standardization – unifies patterns, conventions, or APIs across a codebase.
code-mining – identifies, flags, or extracts patterns without transforming. Use if codemod is for detection-only.
Rule of thumb: Pick one primary type tag per codemod. Avoid mixing breaking-change and feature-adoption in the same codemod.2. Target Version TagsUse these to indicate the framework/library version the codemod prepares for.
Format: vX or vX-to-vY (for upgrades).
Examples:
v17-to-v18 (React 17 → 18)
v5-to-v6 (React Router 5 → 6)
v16 (Angular 16 breaking changes)
Rule of thumb: If the codemod is version-specific, always tag it.3. Framework / Library / SDK TagsAlways add the ecosystem name to improve discoverability.
Examples:
react
nextjs
nodejs
angular
msw
i18next
Rule of thumb: Use the official, common name of the framework/library.4. Example Tag SetsHere are some examples to illustrate how tags combine:
The workflow.yaml file defines your Codemod package’s workflow. A workflow is a collection of nodes that are executed in order. A workflow has four top-level keys:
Nodes are execution units in your workflow. They can be automatic or manual, depend on other nodes, and may define strategy (e.g., matrix), trigger, runtime, env, and an ordered list of steps.
Executes a JavaScript/TypeScript codemod using ast-grep for pattern matching and AST manipulation. JSSG is the primary transformation engine for Codemod, combining the speed of ast-grep with the flexibility of JavaScript.JSSG steps are useful for:
Complex transformations requiring conditional logic or loops
Transforms that need access to workflow parameters or state
To use a JSSG step:
1
Create a JSSG codemod
Create a JS/TS file under scripts/ that exports a transform function. The function receives a parsed file (SgRoot) and returns modified code or null for no changes.
Calls an AI agent with a prompt. This is helpful when your workflow requires leveraging LLM intelligence for more complex tasks for capabilities beyond deterministic transformations.To use a AI step:
1
Set the environment variables:
You can either set the environment variables in your shell or in your environment file.
.env
Copy
LLM_API_KEY=YOUR_KEYLLM_PROVIDER=openai # or anthropic, azure_openaiLLM_MODEL=gpt-4o # or the model you want to useLLM_BASE_URL=https://api.openai.com/v1 # or the base URL of the provider you want to use
2
Add an AI step to your workflow:
workflow.yaml
Copy
steps: - name: Review diffs with AI ai: prompt: | Summarize risky changes and suggest tests. model: "gpt-4o"
Executes ast-grep using declarative YAML rules. Use for simple, fast pattern matching when you don’t need programmatic logic.When to use YAML ast-grep:
Version pinning: specify an exact version in source (e.g., @scope/[email protected]) for reproducible runs. If you omit the version, the latest published version is used.
Step-level environment variables. For codemod steps, these are forwarded to the invoked workflow as parameters with an env_ prefix (e.g., FOO → env_FOO). They are not applied to the OS environment of the nested workflow.
Aggregate multiple codemods:
You can aggregate multiple codemods by adding more than one codemod step in the same node. A Codemod package may itself orchestrate other codemods, enabling nested compositions for larger upgrades.
workflow.yaml
Copy
steps: - name: Convert `createRequireFromPath` to `createRequire` codemod: source: "@nodejs/create-require-from-path" - name: Handle DEP0147 (`fs.rmdir` to `fs.rm`) codemod: source: "@nodejs/rmdir"
Steps in a node run sequentially from top to bottom.
Use depends_on or a matrix strategy across multiple nodes for gating/parallelism.
If a step fails, the node fails and subsequent steps in that node are skipped.
State enables workflows to persist data across runs and coordinate work across repositories and teams:
Sharding: Distribute work across teams or repositories
Progress tracking: Resume interrupted migrations without losing work
Coordination: Maintain consistency across related codebases
The Codemod app provides centralized state management for large-scale refactoring across many repos. Pro codemods like i18n codemod use state to coordinate multi-repo migrations.
In shell steps - parameters become environment variables with PARAM_ prefix:
workflow.yaml
Copy
- name: Run script run: | echo "Library: $PARAM_LIBRARY"
In codemod steps - forwarded with env_ prefix:
workflow.yaml
Copy
- name: Run nested codemod codemod: source: "@org/package" env: LIBRARY: ${{ params.library }}# The nested workflow receives env_LIBRARY
Common parameter use cases:
Sharding configuration: Method (directory, codeowner) and targets
PR settings: Size limits, auto AI review, pre/post run scripts
Enterprise Features: In the Codemod app, you can configure parameters visually through the UI. See Campaigns for running parameterized workflows at scale.
Matrix values are exposed differently per step type:In jssg transforms - access via options.matrixValues:
scripts/codemod.ts
Copy
const transform: Transform<TSX> = async (root, options) => { const team = options.matrixValues?.team; const shardId = options.matrixValues?.shardId; // Use for sharding logic if (team && !isOwnedByTeam(root.filename(), team)) { return null; // Skip files not owned by this team }};
All state updates must be valid JSON if not a primitive. Updates are applied only if the task exits successfully.
Container Runtimes
Planned feature: containerized execution (e.g., Docker/Podman). Currently, workflows run in the host shell. When available, you’ll be able to specify a runtime per node or template.
State Management & Persistence
Workflow state is persisted after every task. If interrupted, you can resume from the last saved state—no work is lost.
Matrix Master Task
For matrix nodes, a master task aggregates the status of all generated tasks.
If all child tasks complete, the master is Completed. If any fail, the master is Failed.
Cyclic Dependency Example
If your workflow has a cycle:
workflow.yaml
Copy
nodes: - id: a name: Task A depends_on: [b] steps: - name: Task A run: echo "Task A" - id: b name: Task B depends_on: [a] steps: - name: Task B run: echo "Task B"
You’ll see:
console
Copy
✗ Workflow definition is invalidError: Cyclic dependency detected: a → b → a
This error is shown when you run npx codemod workflow validate or npx codemod workflow run on a workflow with a cyclic dependency.