Skill v1.0.0
currentAutomated scan100/100name: ast-grep description: Use ast-grep for structural (AST-aware) code search and refactoring instead of plain ripgrep when the intent depends on code structure — not just text matching. Triggers on refactors, codemods, "find all X that don't Y", or any search where naive grep would miss edge cases. version: 1.0.0 trigger: > Any request that requires understanding code structure (not just text):
- "Find all async functions without try/catch"
- "Rewrite every useState<X>(y) to useSignal<X>(y)"
- "Find React components using a specific hook"
- "Find functions with >3 parameters"
- "Replace console.log only inside class methods"
- Any refactor spanning > 5 files
ast-grep
Structural code search. You understand code's abstract syntax tree, not just its text.
When to Run
| Task | Tool | |
|---|---|---|
| Find a string literal | rg | |
| Find a comment | rg | |
| Find all exports | rg (fast enough) | |
| Find all async functions that await outside try/catch | `ast-grep` | |
Refactor foo(bar) → foo.method(bar) everywhere | `ast-grep` | |
| Rename a class across a TypeScript codebase | `ast-grep` (catches shorthand, destructuring, types) | |
| Find components that receive a specific prop | `ast-grep` |
Default to rg for text; escalate to ast-grep when the pattern needs grammar awareness.
Installation
brew install ast-grep # macOScargo install ast-grep # cross-platformnpm install -g @ast-grep/cli # Node-friendly
Verify: ast-grep --version (should print a 0.x.x or later).
Basic Usage
Find pattern
# Find all console.log calls inside class methodsast-grep --lang ts --pattern 'class $_ { $$ { console.log($$$) } $$ }'# Find React components using useEffect with empty depsast-grep --lang tsx --pattern 'useEffect($_, [])'# Find async functions without try/catchast-grep --lang ts --pattern 'async function $NAME($$) { $$ }' \| grep -v 'try {'
Rewrite in place
# Convert var → let (demonstrative; use at your own risk)ast-grep --lang js \--pattern 'var $NAME = $VAL' \--rewrite 'let $NAME = $VAL' \--update-all
Rule files
For complex patterns, write a YAML rule in .ast-grep/rules/:
# .ast-grep/rules/no-console-in-prod.ymlid: no-console-in-prodlanguage: typescriptrule:pattern: console.log($$$)not:inside:kind: if_statementhas:pattern: process.env.NODE_ENV === 'development'message: "console.log outside dev-mode guard"severity: error
Run: ast-grep scan.
Agent Protocol
When the user asks for a code search that depends on structure:
- Decide the right tool. Is this pattern purely textual? Use
rg. Does it depend on AST context (inside class, function, expression)? Useast-grep. - Write the pattern. Use metavariables
$_(wildcard),$NAME(named),$$$(multiple). Test on a single file first. - Scope the search. Always pass
--lang <lang>and a path argument — not the whole repo if you can avoid it. - Preview before rewriting. Never pass
--update-allwithout first running without it and reading the output. - For refactors > 10 files, write a rule file in
.ast-grep/rules/and commit it. Reproducibility > one-off commands.
Language Support
ast-grep ships first-class support for: TypeScript, TSX, JavaScript, JSX, Python, Rust, Go, Java, Kotlin, Swift, C, C++, C#, Ruby, PHP, HTML, CSS, YAML, JSON, Bash.
If your language is missing, check the ast-grep playground for tree-sitter grammar coverage.
Common Patterns Cheat Sheet
| Intent | Pattern | |
|---|---|---|
| Any function with > N args | function $NAME($A, $B, $C, $D, $$$) | |
| React class component | class $_ extends React.Component { $$ } | |
| Async function | async function $_($$) { $$ } | |
| Arrow function | ($$) => $_ | |
| Call with specific first arg | $FN("specific-arg", $$) | |
| TypeScript generic call | $FN<$T>($$) |
Never
- Never use ast-grep for plain string/text search —
rgis 10x faster and the right tool - Never run
--update-allwithout first running the same pattern without it and reading the diff - Never leave complex patterns as one-off commands — commit them as rule files in
.ast-grep/rules/ - Never run against
node_modules/,vendor/,dist/, or build output — always scope with a path argument - Never trust a rewrite across a codebase without running the test suite after
Credits
Reference from the official ast-grep AI docs, prompting pattern originally from Kieran Klaassen on X.