Quick Reference
Core Types
SgRoot<L>- Represents a parsed fileSgNode<L>- Represents any AST nodeEdit- Single text replacementRuleConfig- Pattern matching configuration
Essential Methods
root.root()- Get root AST noderoot.filename()- Get file pathroot.relativeFilename()- Get file path relative to the target directorynode.find(rule)- Find first matchnode.findAll(rule)- Find all matchesnode.replace(text)- Create editnode.commitEdits(edits)- Apply edits
Runtime and built-ins
JSSG is a JavaScript runtime similar to Node.js with most Node globals/modules (for example,
fs, process). It is powered by QuickJS, uses LLRT for Node module compatibility, and oxc for module resolution. ast-grep is available as a built-in module. See Parse Helpers for parsing functions.codemod:ast-grep— parsing, traversal, pattern matchingcodemod:llm— engine-owned text generation for codemods that declare thefetchcapabilitycodemod:workflow— shared state and workflow integrationcodemod:metrics— metrics collection across filescodemod:runtime— progress, warning, cancellation, and explicit failure hooks
codemod:llm is also supported when you publish a codemod package, so published JSSG codemods can keep importing it without bundling errors.
Transform Function
Every JSSG codemod exports a transform function:Types vs values:
SgRoot and SgNode are TypeScript types (not runtime values). At runtime, the codemod:ast-grep module provides functions such as parse and parseAsync (see Parse Helpers).string- Modified code (if identical to input, treated as unmodified)null- No changes neededundefined- Same as null- Other types - Runtime error
options argument includes the execution context for the current run, including params, matches, matrixValues, dryRun, and targetDir.
SgRoot API
The root object provides access to the parsed file:SgNode
Get the root AST node of the file.
string
Get the file path or “anonymous” for ad-hoc parsing.
string
Get the file path relative to the target directory when available.
string
Get the full source code of the file.
void
Write content to this file. Only valid for files obtained via
definition() or references() — cannot be called on the current file being processed.void
Rename the current file to a new path. If relative, resolved against the file’s parent directory. Can only be called once per file. See File Renaming for details.
SgNode API
Navigation Methods
SgNode | null
Find the first matching descendant node.
SgNode[]
Find all matching descendant nodes.
SgNode | null
Get the parent node.
SgNode[]
Get all child nodes.
SgNode | null
Get child at specific index.
SgNode | null
Get next sibling node.
SgNode[]
Get all following sibling nodes.
SgNode | null
Get previous sibling node.
SgNode[]
Get all previous sibling nodes.
SgNode[]
Get all ancestor nodes up to root.
SgRoot
Get the root SgRoot object.
Node Properties
string
Get the text content of this node.
string
Get the node type (e.g., “function_declaration”, “arrow_function”).
Range
Get the source position range.
boolean
Check if node is of specific type.
boolean
Check if node has no children.
boolean
Check if node is a named AST node.
boolean
Check if node is a named leaf node.
number
Get the unique identifier of this node.
Field Access
SgNode | null
Get first child in named field.
SgNode[]
Get all children in named field.
Pattern Matching
boolean
Test if current node matches a pattern.
boolean
Check if node is inside a matching ancestor.
boolean
Check if node has matching descendant.
boolean
Check if node precedes a matching sibling.
boolean
Check if node follows a matching sibling.
Capture Methods
SgNode | null
Get captured node by name from pattern.
SgNode[]
Get all captured nodes with same name.
string | null
Get transformed text of captured node.
Editing Methods
Edit
Create a replacement edit for this node.
string
Apply array of edits and return new code.
Semantic Analysis Methods
Semantic analysis is only supported for JavaScript/TypeScript (using oxc) and Python (using ruff). For other languages, these methods return null or empty arrays. See Semantic Analysis for details.
DefinitionResult | null
Get the definition for the symbol at this node’s position. Returns an object with
node (the definition SgNode) and root (the SgRoot for the file containing the definition), or null if not found.Array<FileReferences>
Find all references to the symbol at this node’s position. Returns an array of objects, each with
root (SgRoot for the file) and nodes (array of reference SgNodes).Pattern Matching
JSSG uses ast-grep patterns to find code structures. Patterns are more powerful than regex because they understand code syntax.Basic Patterns
Pattern Syntax
$NAME- Capture a single node (e.g.,$ARG,$NAME)$$$ARGS- Capture multiple nodes (e.g.,$$$ARGS,$$$PARAMS)$...- Match any number of nodes$NAME:kind- Capture only specific node types
Rule Configuration
Rules are authored as plain JavaScript objects with the same semantics as ast-grep’s YAML rule config. See: ast‑grep YAML Rule Config and Rule Config Guide.
Relational Patterns
Advanced Pattern Composition
Rule References
Usematches to reference named rules defined in utils:
Constraint System
Useconstraints to define reusable rule patterns and reference them with matches:
Traversal Control
UsestopBy to control how deep the search traverses:
Select (optional)
Use a selector to skip files that don’t contain your target shape:When a selector is provided, the engine pre‑computes matches; if none are found, the file is skipped (your transform won’t be called).
Basic Example
Here’s a complete example that replacesconsole.* calls with logger.*:
Types
Core Types
{ startPos: number; endPos: number; insertedText: string }
Single text replacement range.
{ line: number; column: number; index: number }
Source position.
{ start: Position; end: Position }
Source span.
Edit Interface
Best Practices
1. Be Explicit with Transformations Always include explicit checks before accessing node properties:Parse Helpers
Use parse/parseAsync to sub‑parse embedded languages or strings extracted from your AST (for example, CSS‑in‑JS, HTML templates, or SQL in template literals). Parse the content, run queries on the resulting tree, and use the findings to inform edits in the host file.SgRoot
Parse raw source into an SgRoot.
Promise<SgRoot
Async variant of parse.
File Renaming
Useroot.rename() to rename a file alongside content changes. This is useful for codemods that convert between file formats (e.g., .less → .css, .js → .ts, .cjs → .mjs).
Path resolution:
- Relative paths are resolved against the current file’s parent directory (e.g.,
"newname.css"renames in the same directory). - Absolute paths are used as-is.
- The resolved path must stay within the target directory.
rename()can only be called once per file. Calling it again throws an error.
Multi-File Transforms with jssgTransform
Promise<string | null>
Apply a transform function to a secondary file. Reads the file, parses it with the given language, calls the transform, and collects the result. Returns the transformed content string, or null if unchanged.
jssgTransform() when a change in one file requires a corresponding change in another file. For example, renaming a .less file to .css while also updating its import path in a .tsx file.
File changes from
jssgTransform are collected and applied alongside the primary file’s changes — the secondary file is not written to disk mid-transform. This ensures atomicity.- The file path must be within the target directory.
- In test mode,
jssgTransformis a no-op and returnsnull. - The
transformFnreceives the same(root, options)signature as your main transform, includingparamsandmatrixValuesfrom the parent execution. - You can call
jssgTransformmultiple times to transform multiple secondary files.
Async Transformations
JSSG supports async operations for complex transformations:- Loading configuration files
- Analyzing project structure
- Making API calls for metadata
- Cross-file analysis
Advanced Patterns
Multi-File Context
Access information from other files in your project:Custom Node Matchers
Create reusable, complex matchers:Real-world Example: Next.js Route Props
Here’s a complete example that adds type annotations to Next.js page components:- Type guards: Checking node types before operations
- Field access: Safely accessing AST fields with optional chaining
- Conditional logic: Different behavior based on file context
- Complex patterns: Finding and transforming specific code structures
- Real-world patterns: Practical Next.js-specific transformations
Performance Optimization
For large codebases, optimize your traversal:- Early returns to skip non-applicable files
- Single traversal for multiple patterns
- Batch all edits before committing
- Use specific patterns over generic ones
Decision Guides
Selecting files vs selecting nodes
Selecting files vs selecting nodes
Use getSelector to skip entire files quickly; use find/findAll inside files to select nodes precisely.
pattern vs kind vs regex vs relations
pattern vs kind vs regex vs relations
Prefer pattern for clarity, add kind for stricter scopes, use relations for context, reserve regex as a last resort.
Return null vs same string
Return null vs same string
Return null to indicate “skipped”; return the same string when edits result in identical output — both are treated as unmodified by the engine.
Troubleshooting
Transformation Not Applied
Transformation Not Applied
Issue: Your codemod runs but doesn’t make changes.
Debug steps:
Debug steps:
Type Errors
Type Errors
Issue: TypeScript compilation errors.
Solution: Ensure proper type imports and annotations:
Solution: Ensure proper type imports and annotations:
Test Failures
Test Failures
Issue: Tests fail unexpectedly.
Debug with verbose output:
Update snapshots if changes are intended:
Debug with verbose output:
Update snapshots if changes are intended:
Pattern Matching Issues
Pattern Matching Issues
Issue: Patterns don’t match expected code.
Use the ast-grep playground to test patterns:
Use the ast-grep playground to test patterns:
- Visit https://ast-grep.github.io/playground/
- Paste your code sample
- Test different patterns
- Use the AST viewer to understand structure
Performance Optimization
Performance Optimization
For large codebases:
- Early returns: Skip files that don’t need transformation
- Efficient patterns: Use specific patterns over generic ones
- Batch operations: Collect all edits before committing
- Limit traversals: Combine related searches
Language kinds and editor IntelliSense are available via codemod:ast-grep/langs/*. E.g.,
import { TSX } from "codemod:ast-grep/langs/tsx".LLM Generation
codemod:llm when your codemod needs engine-provided text generation. The engine owns provider credentials, model selection, and usage accounting.
Types
object
Request payload for
generate(...).string
required
The user prompt sent to the engine-owned LLM client.
string
Optional system instructions applied before the prompt.
Record<string, unknown> | boolean
Optional structured-output schema hint forwarded to the engine.
number
Optional maximum token budget for the generation request.
object
Response returned by
generate(...).string
required
Generated text returned by the engine-owned LLM client.
Functions
(request: LlmRequest) => Promise<LlmResponse>
Generates text through the engine-owned LLM client.
Notes
- Your codemod must declare the
fetchcapability beforecodemod:llmcan be used. - Provider credentials and model selection come from the engine, not from your codemod.
- Provider-reported usage is recorded by the engine automatically.
Runtime Hooks
Types
string | number | boolean | null | Record<string, RuntimeMeta | undefined> | RuntimeMeta[]
Optional structured metadata that can be attached to runtime events and failures.
Functions
(message: string, meta?: RuntimeMeta) => void
Emits a structured progress event and refreshes the engine heartbeat.
(message: string, meta?: RuntimeMeta) => void
Emits a structured warning without failing the task.
(unitId: string, meta?: RuntimeMeta) => void
Sets the current logical execution unit for diagnostics, typically a file path or shard label.
(message: string, meta?: RuntimeMeta) => never
Fails the current file or execution unit immediately. The runtime currently treats this as terminal for the running task.
(message: string, meta?: RuntimeMeta) => never
Fails the current step immediately and marks the task as failed.
() => boolean
Returns
true if the current task has been canceled and the codemod should stop cooperatively.Notes
- Hooks are the preferred way to report semantic failures or progress to workflows and the TUI.
- Uncaught exceptions still fail the task, but they provide less structured context.
codemod:runtimerequires a runtime version that includes runtime-hook support.