ast-grep
Find complex code patterns and perform safe structural code transformations across projects using ast-grep. Use when analyzing code structures, searching for patterns, refactoring codebases, or debugging.
Installation
Follow the repository instructions for this skill and your agent. Review the files and dependencies before adding it to your workflow.
View source ↗GuidesSkill instructions
ast-grep
Structural code search and rewriting using AST matching instead of regex.
Contents
- Pattern Syntax
- Basic Search
- Search and Replace
- Advanced Scan with Rules
- Common Refactoring Examples
- Project Setup
Pattern Syntax
ast-grep uses pattern placeholders to match and capture AST nodes:
| Pattern | Description |
|---|---|
$VAR |
Match a single AST node and capture it as VAR |
$$$VAR |
Match zero or more AST nodes (spread) and capture as VAR |
$_ |
Anonymous placeholder (matches any single node, no capture) |
$$$_ |
Anonymous spread placeholder (matches any number of nodes) |
Shell quoting tip: Escape $ as \$VAR or wrap the pattern in single quotes to avoid shell expansion.
Supported Languages
javascript, typescript, tsx, html, css, python, go, rust, java, c, cpp, csharp, ruby, php, yaml
Commands
| Command | Description |
|---|---|
ast-grep run |
One-time search or rewrite (default) |
ast-grep scan |
Scan and rewrite by configuration |
ast-grep test |
Test ast-grep rules |
ast-grep new |
Create new project or rules |
ast-grep lsp |
Start language server |
Usage
Basic Search
Find patterns in code:
# Find console.log calls
ast-grep run --pattern 'console.log($$$ARGS)' --lang javascript .
# Find React useState hooks
ast-grep run --pattern 'const [$STATE, $SETTER] = useState($INIT)' --lang tsx .
# Find async functions
ast-grep run --pattern 'async function $NAME($$$ARGS) { $$$BODY }' --lang typescript .
# Find Express route handlers
ast-grep run --pattern 'app.$METHOD($PATH, ($$$ARGS) => { $$$BODY })' --lang javascript .
# Find Python function definitions
ast-grep run --pattern 'def $NAME($$$ARGS): $$$BODY' --lang python .
# Find Go error handling
ast-grep run --pattern 'if $ERR != nil { $$$BODY }' --lang go .
Search and Replace (Dry Run)
Preview refactoring changes without modifying files:
# Replace == with === (preview)
ast-grep run --pattern '$A == $B' --rewrite '$A === $B' --lang javascript .
# Convert function to arrow function (preview)
ast-grep run --pattern 'function $NAME($$$ARGS) { $$$BODY }' \
--rewrite 'const $NAME = ($$$ARGS) => { $$$BODY }' --lang javascript .
# Replace var with let (preview)
ast-grep run --pattern 'var $NAME = $VALUE' --rewrite 'let $NAME = $VALUE' --lang javascript .
# Add optional chaining (preview)
ast-grep run --pattern '$OBJ && $OBJ.$PROP' --rewrite '$OBJ?.$PROP' --lang javascript .
Apply Changes
Apply refactoring to files:
# Apply changes (use --update-all)
ast-grep run --pattern '$A == $B' --rewrite '$A === $B' --lang javascript --update-all .
Advanced Scan with Rules
Use inline rules for complex pattern matching with logical operators:
# Find functions containing await
ast-grep scan --inline-rules '{"id": "async-fn", "language": "javascript", "rule": {"kind": "function_declaration", "has": {"pattern": "await $EXPR"}}}' .
# Find nested if statements
ast-grep scan --inline-rules '{"id": "nested-if", "language": "javascript", "rule": {"kind": "if_statement", "inside": {"kind": "if_statement"}}}' .
# Find console.log inside catch blocks
ast-grep scan --inline-rules '{"id": "catch-log", "language": "javascript", "rule": {"pattern": "console.log($$$ARGS)", "inside": {"kind": "catch_clause"}}}' .
Rule Operators
Rules support these operators for complex matching:
-
all: All conditions must match -
any: Any condition must match -
not: Negate a condition -
inside: Node must be inside another pattern -
has: Node must contain another pattern -
kind: Match AST node type -
pattern: Match a code pattern
Common Refactoring Examples
JavaScript/TypeScript
# Convert require to import
ast-grep run --pattern 'const $NAME = require($PATH)' \
--rewrite 'import $NAME from $PATH' --lang javascript .
# Simplify boolean return
ast-grep run --pattern 'if ($COND) { return true } else { return false }' \
--rewrite 'return !!$COND' --lang javascript .
# Convert Promise.then to async/await
ast-grep run --pattern '$PROMISE.then($CALLBACK)' \
--rewrite 'await $PROMISE' --lang javascript .
Python
# Convert string formatting
ast-grep run --pattern '"%s" % ($ARGS)' \
--rewrite 'f"{$ARGS}"' --lang python .
# Find deprecated function calls
ast-grep run --pattern 'old_function($$$ARGS)' --lang python .
React
# Find class components
ast-grep run --pattern 'class $NAME extends React.Component { $$$BODY }' --lang tsx .
# Find useEffect with empty deps
ast-grep run --pattern 'useEffect($CALLBACK, [])' --lang tsx .
Workflow
-
Search first: Use
ast-grep run --patternto find matches -
Preview changes: Add
--rewriteto see what would change - Verify output: Review the diff output carefully
-
Apply changes: Add
--update-allto modify files - Test: Run tests to verify refactoring didn't break anything
Project Setup
Create a new ast-grep project with rules:
# Initialize project with sgconfig.yml
ast-grep new
# Create a new rule
ast-grep new rule
# Create a new test for rules
ast-grep new test
Testing Rules
# Test all rules in project
ast-grep test
# Test with specific config
ast-grep test -c ./sgconfig.yml
Language Server
# Start LSP for editor integration (use tmux for background)
tmux new -d -s ast-grep-lsp 'ast-grep lsp'
Tips
- Start with simple patterns and refine
- Use
$_for parts you don't care about capturing - Use
$$$for variable-length matches (arguments, statements) - Test patterns on a single file first:
ast-grep run --pattern '...' --lang js path/to/file.js - Use JSON output for programmatic processing:
ast-grep run --pattern '...' --json - Use
ast-grep newto scaffold rules and tests
Related Skills
- typescript: Use ast-grep for TypeScript-specific refactoring patterns.
- jscpd: Combine with duplicate detection to find and consolidate similar code.
Examples
Read the usage examples in the source repository.
View source ↗Source history
- Indexed on
- 2026-01-20
- Index updated
- 2026-01-26
- Branch
- main
Index and sync dates describe this directory. View the source repository for code history.
GitHub ↗chat Comments (0)
Sign in to join the discussion and leave a comment.
No comments yet. Be the first to share your thoughts!