Quickstart
New to Codemod? Follow the step-by-step guide to scaffold, test, and publish your first codemod.
Command Relationships
The Codemod CLI provides different commands for different stages of development:High-Level Commands (Production)
Quick Testing Commands (Development)
Package Lifecycle
When to use what: Use
codemod workflow run for orchestrated, multi-step transformations with parameters. Use codemod jssg run for quick testing of a single jssg transform during development.Telemetry
When analytics are enabled, the CLI sends product telemetry to PostHog (and a separate Scarf gateway for install/usage signals). Logged-in users are keyed by their Codemod account id. Anonymous installs use a local telemetry id and are never aliased to an account. For logged-in sessions only, the CLI may also send a separate PostHog$set with the account
email so dashboards can show people instead of raw UUIDs. That update is PostHog-only (not
Scarf), deduped locally, and skipped when you opt out.
Disable all of this for a single invocation with --disable-analytics, or by setting
DISABLE_ANALYTICS=true / DISABLE_ANALYTICS=1 in the environment. The flag works on explicit
commands and on implicit package runs such as npx codemod @org/package --disable-analytics.
More detail: Telemetry compliance.
CLI Command Reference
Codemod CLI is accessible using thenpx codemod command. The following commands and options are available:
codemod ai
In an interactive terminal, bare
npx codemod opens a launcher. In npm-based usage, that launcher refreshes to the latest published CLI before prompting you to create a package or run one from the registry. In non-interactive contexts, the CLI prints next steps and exits with status 1.ai
Install the codemod MCS skill package, configure Codemod MCP, and install the universal /codemod entrypoint where the harness supports it.
--no-interactive to skip prompts and use flags/defaults directly.
With --harness auto (the default), install first checks whether it is running inside a coding agent (Claude Code, Codex, Cursor, OpenCode, Goose or Antigravity) and sets up that agent. Otherwise it looks for an agent folder or config file in the project, such as .claude, .cursor, .codex or opencode.json, and prefers Claude Code when it finds several. If it finds neither, it sets up Claude Code and warns, so pass --harness to choose another agent. The output says which agent was set up and why, marks files that a re-run left unchanged as up to date, and ends with numbered next steps for that agent, such as approving the MCP server in Claude Code or trusting the folder in Codex.
Along with skill files, install writes or updates a Codemod MCP server entry. Project installs (--project) write a portable launcher pinned to the CLI version that ran the install, so the config can be committed and used on other machines and checkouts:
--user) stay on the current machine, so they launch the installed codemod executable directly. If the CLI itself was run through npx, its cached executable is temporary, so user installs fall back to codemod on PATH (outside the npx cache) or the same pinned npx launcher. Re-running ai --project repairs one known broken entry without --force: a project entry whose command is an absolute path to an executable inside npm’s npx cache (_npx), which earlier releases wrote. Every other existing codemod entry is kept and reported as a conflict, including absolute paths outside the npx cache, older pinned codemod@<version> launchers, and all user-scope entries. Re-run with --force to replace it.
Prerequisites for project installs:
- The project MCP launcher needs Node.js and npm (
npx) on every machine that uses the committed config. The first launch of a pinned version downloads it from the npm registry unless it is already in the npm cache. - If npm is not available, use
--userwith an installedcodemodexecutable instead. - The Claude periodic update hook runs a POSIX shell script. Claude Code runs hook commands with
shon macOS and Linux and with Git Bash on Windows, so Windows machines need Git for Windows; the hook does not run under PowerShell.
opencode.json using the Opencode-specific mcp schema instead of mcpServers.
MCP config paths by harness and scope:
claude:./.mcp.json(project),~/.claude.json(user, the same fileclaude mcp add -s userwrites; other keys in it are kept)goose:./.goose/mcp.json(project),~/.config/goose/mcp.json(user)opencode:./opencode.json(project),~/.config/opencode/opencode.json(user)cursor:./.cursor/mcp.json(project),~/.cursor/mcp.json(user)codex(CLI + macOS app):./.codex/config.toml(project),~/.codex/config.toml(user) under[mcp_servers.codemod]
--force to overwrite it. For Opencode, Codemod leaves any legacy ./.opencode/mcp.json or ~/.opencode/mcp.json file in place to avoid deleting unrelated MCP servers.
ai also upserts a managed Codemod discovery section in harness discovery guides (project root for --project, home directory for --user) without duplicating entries:
claude:CLAUDE.mdgoose:AGENTS.mdand.goosehintscursor:AGENTS.mdopencode:AGENTS.mdcodex:AGENTS.mdaialso installs/codemodwhere the harness has a native command or workflow file surface:claude:./.claude/commands/codemod.md(project),~/.claude/commands/codemod.md(user)goose:~/.config/goose/recipes/codemod.yaml+~/.config/goose/config.yamlregistration (user only)opencode:./.opencode/commands/codemod.md(project),~/.config/opencode/commands/codemod.md(user)cursor:./.cursor/commands/codemod.md(project),~/.cursor/commands/codemod.md(user) The installed/codemodcommand routes by intent:- create, scaffold, or refine codemods -> codemod authoring flow
- search, run, or apply existing codemods -> registry discovery and execution flow
SKILL.md: the main skill instructions and Codemod-specific authoring and execution defaultsagents/openai.yaml: the Codemod agent interface definition used by compatible harnessescommands/codemod.md: the/codemodcommand routing rules for harnesses with a native command surface
npx codemod ai docs: list docs resources exposed through the CLInpx codemod ai docs <resource-id>: read a specific docs resource such ascodemod-cli,codemod-creation-workflow, orcodemod-troubleshootingnpx codemod ai dump-ast <file>ornpx codemod ai dump-ast --: inspect AST shape for a file or stdinnpx codemod ai node-types <language>: inspect tree-sitter node kinds for a languagenpx codemod ai call validate_codemod_package --input '{"package_path":"."}': validate whether a codemod package still contains starter scaffold markers or other package-surface issuesnpx codemod ai feedback --category <category> --message <message>: submit short anonymous platform feedback after consent is recorded
ai also wires a periodic, cooldown-protected update check trigger:
claude:hooks.SessionStartcommand in./.claude/settings.json(project) or~/.claude/settings.json(user). The project hook runs"$CLAUDE_PROJECT_DIR"/.claude/codemod/periodic-update/check-updates.sh, so it keeps working after the project is cloned or moved. Re-runningaireplaces a project hook that an earlier install wrote with an absolute runner path, including one written from a different checkout. Only unmodified generated hooks with an unambiguous absolute runner command are migrated automatically. Commands containing whitespace (including old unquoted paths with spaces), quoting, arguments or shell syntax are preserved, as are hooks with custom matchers, timeouts or other fields. Review and remove obsolete preserved hooks manually when moving a checkout; install adds the portable hook without deleting those commands.cursor:hooks.afterAgentResponsecommand in./.cursor/hooks.json(project) or~/.cursor/hooks.json(user)opencode: plugincodemod-periodic-update.jsin./.opencode/plugins/(project) or~/.config/opencode/plugins/(user), listening tosession.idlegoose: managedcodemod-periodic-updateblock in./.goosehints(project) or~/.config/goose/.goosehints(user) as fallback guidancecodex:notify = ["sh", "<runner>"]in./.codex/config.toml(project) or~/.codex/config.toml(user) Managed update policy is install-flag driven and shared by install-time reconciliation and periodic checks:--update-policy <manual|notify|auto-safe>(default:auto-safe)--update-source <local|registry|URL>(default:registry)--require-signed-manifestor--allow-unsigned-manifest(optional override)--update-sourceonly acceptslocal,registry, or an absolutehttp(s)URL (legacyregistry:/url:aliases are rejected). Project periodic runners use the same pinnednpx -y codemod@<installing CLI version>launcher as project MCP, even when another global CLI version is installed. User runners retain their local executable/PATH fallback. Periodic runs enforce signed manifest verification via--require-signed-manifestin the generated runner command. After install, restart or reload your harness session so newly installed skills and command entrypoints are picked up.
ai feedback
Submit short anonymous platform feedback for Codemod AI, MCP, JSSG, workflows, docs, CLI, registry, or related surfaces. The command records anonymous feedback consent in the user-wide Codemod config, including the timestamp at which this OS user allowed feedback submission.
jssg, workflow, ai-docs, mcp, cli, registry, package-validation, and other.
Examples:
ai update
Run managed update reconciliation/apply through CLI (same policy engine used by periodic hooks).
ai update automatically falls back to an install flow and then applies update reconciliation.
ai performs internal skill validation checks during install flow.
ai list
List installed Codemod skills for a harness.
codemod ai again or troubleshooting harness setup.
ai dump-ast
Dump AST nodes for a source file or stdin using the same parser surface exposed through Codemod MCP.
- Omit
FILEor pass-to read from stdin. - If you do not pass
--language, the CLI infers it from the file extension when possible and otherwise defaults totsxfor stdin.
ai node-types
Print tree-sitter node types for a supported language.
ai docs
List, read, or search Codemod AI documentation resources from the CLI.
- Run without a query to list available docs-backed resources.
- Pass a resource name or URI to read it.
- Pass a search phrase to search across available resources.
ai tools and ai tool
Inspect MCP-equivalent tools exposed by the CLI.
ai toolslists available tool names and descriptions.ai tool <name>prints metadata and the JSON input schema for a single tool.
ai call
Call an MCP-equivalent tool directly from the CLI with JSON input.
- Omit
--inputto pass an empty object ({}). - Use
--input @request.jsonto load input from a file. - Use
--input -to read JSON input from stdin.
ai resources and ai resource
Inspect and read MCP-equivalent resources exposed by the CLI.
ai resourceslists the available resource names and URIs.ai resourcereads one resource by URI or resource name.
Package skill install (prompted from package run)
Install a package skill from registry metadata into harness skill paths. The installer copies the authored skill directory recursively from the package (agents/skill/<skill-name>/), including any additional files you add (for example extra .md references).
This flow also updates managed Codemod discovery hints in harness discovery guides (CLAUDE.md for Claude, AGENTS.md and .goosehints for Goose, AGENTS.md for Cursor/OpenCode/Codex) without duplication, then prompts you to restart/reload the harness session.
npx codemod <package-id> prompts for harness/scope/overwrite when installable skill behavior is available.
Behavior-aware package runtime:
- Workflow-only package:
npx codemod <package-id>runs the workflow behavior. - Skill-only package:
npx codemod <package-id>does not run a no-op workflow. It returns install guidance and, in interactive terminals, can prompt to install the skill. - Workflow + skill package:
npx codemod <package-id>runs workflow behavior and can optionally prompt to install skill behavior after run completion. - Multi-workflow package: when the package’s
codemod.yamldeclares multiple workflows underworkflows:, the default workflow runs unless you pass--workflow <name>. In an interactive terminal with no flag, the CLI shows a picker.
Example machine-readable failure (
--format json):
codemod workflow
Manage and execute Codemod packages.
A Codemod package is a directory containing workflow.yaml and transformation scripts. Workflows orchestrate multiple steps using different engines (jssg, YAML ast-grep, shell commands, AI, etc.).
When to use:
- ✅ Production codemods with multiple steps
- ✅ Parameterized transformations
- ✅ Multi-repo orchestration
- ✅ State management and resumption
workflow run
Run a complete Codemod package.
- Use
npx codemod workflow run -w <path>for local Codemod packages and directories - Use
npx codemod <package-name>to run packages directly from the Codemod Registry
Pass key=value pairs to your workflow. Parameters are exposed to jssg transforms via
options.params.In non-interactive runs, execute
install-skill workflow steps instead of skipping them by default.When the package directory’s Errors out if the name doesn’t match any declared workflow, or if the source path is a workflow file (rather than a package directory) — in that case the file IS the workflow.
codemod.yaml declares multiple workflows under workflows:, pick which variant to run.Without this flag, the entry marked default: true runs (or the first entry if none is flagged). When stdin/stdout are interactive and no flag is given, the CLI shows a picker.Write provider-reported nested LLM usage for the current package run to a JSON file.This output is only populated for LLM requests made by nested codemods during The CLI creates parent directories as needed and overwrites the file with the current run’s data.
npx codemod <package-name> or other package-run flows. The file contains aggregated request counts by provider, model, outcome, and token-usage bucket, and it does not include prompts, API keys, or other request payload data.workflow resume
Resume a paused workflow.
In non-interactive resume runs, execute pending
install-skill workflow steps instead of skipping them by default.workflow validate
Validate a workflow file.
workflow validate is capability-aware for codemod packages:
- Workflow-only package: validates workflow behavior.
- Skill-only package: validates workflow
install-skillbehavior plus authored skill layout (agents/skill/<skill-name>/...). - Workflow + skill package: validates both executable workflow and authored skill behavior.
Why validate?Validation catches issues before execution, saving time and preventing runtime errors.
Validation vs. Logical Correctness
Validation vs. Logical Correctness
For workflow behavior,
workflow validate ensures your YAML is syntactically correct and follows the schema, but it cannot verify:- Logical correctness: Whether your workflow does what you intend
- Runtime behavior: How your workflow behaves with real data
- Dependencies: Whether external files/scripts exist
- State consistency: Whether state updates are logically sound
workflow status
Show workflow run status.
workflow list
List workflow runs.
workflow cancel
Cancel a workflow run.
codemod jssg
Run jssg (JS ast-grep) transforms directly without a workflow.
jssg is the primary transformation engine for Codemod. These commands let you test jssg transforms quickly during development.
When to use:
- ✅ Quick testing of a single transform
- ✅ Iterating on pattern matching
- ✅ Development and debugging
- ❌ Multi-step transformations → use
codemod workflow - ❌ Parameterized transforms → use
codemod workflowwith--param - ❌ Production deployments → use
codemod workflowfor orchestration
1
Write your codemod
Create a JS/TS file that exports your codemod logic.
2
Run your codemod
3
Test your codemod
Organize your tests as follows:Use the
tests
simple-transform
input.js
expected.js
multi-file-case
input
file1.js
file2.js
expected
file1.js
file2.js
input/ + expected/ layout when the codemod creates or deletes files. The runner compares the whole directory snapshot but still reports results per file.Then run:jssg run
Run a JS ast-grep (jssg) codemod.
Target language (e.g.,
javascript, typescript, python, java, cpp, php, kotlin, json, yaml, xml, toml, etc.).Include hidden files and directories in the scan.
jssg test
Test a JS ast-grep(jssg) codemod using before/after fixtures. Supports both single-file input.*/expected.* cases and directory snapshot fixtures using input/ + expected/.
Target language (e.g.,
javascript, typescript, python, java, cpp, php, kotlin, json, yaml, xml, toml, etc.).The parent directory containing your test case subdirectories (default:
"tests"). Do not pass a specific test case subdirectory — use --filter instead.A pattern to run only tests whose names match the filter. Single-file fixtures use the test case directory name. Directory snapshot fixtures are still reported per file, using names like
<fixture>_<relative-path>.Comparison strictness level (default:
strict):strict- Exact string equalitycst- Compare Concrete Syntax Trees (includes all tokens, preserves ordering)ast- Compare Abstract Syntax Trees (ignores formatting, preserves ordering)loose- Loose AST comparison (ignores formatting and ordering of unordered nodes like object properties, imports)
Create or update the
expected files with the output of the codemod. For directory snapshot fixtures, this also creates missing expected files and removes stale ones. (-u is a shorthand for --update-snapshots)When should I define a workflow instead?
When should I define a workflow instead?
- When you need to chain multiple codemods or scripts.
- When you want manual review, approval steps, or CI/CD integration.
- When you want to use engines other than ast-grep (e.g., jscodeshift, YAML, or custom scripts).
Why ast-grep?
Why ast-grep?
ast-grep is extremely fast and robust for syntax-aware code transformations. We made it first-class in the CLI for the most common use case, but you can still use any engine via workflows.jssg replicates the ast-grep NAPI, but with a few key differences:
- It’s built into the CLI, so you can run it directly without needing to install it separately.
- It’s built for speed and simplicity, making ast-grep codemods a first-class experience.
codemod init
Initialize a new Codemod package project.
codemod init prompts you to choose between a jssg codemod, multi-step workflow, or agent skill codemod. If you select a workflow, you can optionally scaffold an agent skill.
You’ll also be prompted to create a GitHub Actions publishing workflow. This generates .github/workflows/publish.yml:
- Single codemod repo: Triggers on
v*tags (e.g.,v1.0.0) - Monorepo: Triggers on
*@v*tags (e.g.,my-codemod@v1.0.0) and extracts the codemod name
Project name (defaults to directory name).Required in
--no-interactive mode when the project name cannot be derived from [PATH] (for example, when [PATH] is ., .., or another path without a final directory component).Workflow project type:
ast-grep-js or hybrid.
Mutually exclusive with --skill.Required in --no-interactive mode for workflow packages.More package types (advanced)
More package types (advanced)
shell: Shell script-based codemodsast-grep-yaml: YAML-based ast-grep codemods
Scaffold a skill-only package with a workflow-first template (
workflow.yaml contains install-skill) and authored files under agents/skill/<skill-name>/.The generated SKILL.md uses the authored package skill markers:codemod-compatibility: skill-package-v1codemod-skill-version: 0.1.0
--with-skill and --project-type.Scaffold a workflow + skill package. This keeps executable workflow files, appends an
install-skill node, and creates authored skill files under agents/skill/<skill-name>/.The generated authored skill uses skill-package-v1, not the built-in mcs-v1 core skill marker.Mutually exclusive with --skill.Use defaults without prompts.
In this mode, pass the values that would normally come from prompts.
codemod login
Login to a registry.
codemod logout
Logout from a registry.
codemod whoami
Show current authentication status.
codemod publish
Publish a Codemod package to a registry.
Package metadata (name, version, access level, etc.) is read from
codemod.yaml. See Package Structure for configuration options.Publishing Guide
Learn about all publishing methods including API keys, trusted publishers (OIDC), and CI/CD setup.
codemod unpublish
Remove a package or selected version from the registry.
Examples
Examples
codemod search
Search for packages in the registry.
Examples
Examples
Search for codemods related to React:Filter by language and category:Get results in JSON format:
codemod cache
Manage the local package cache for Codemod packages.
cache info
Show cache information and statistics.
cache list
List cached packages.
cache clear
Clear cache for a specific package, or all packages.
cache prune
Prune old or unused cache entries.