ast-grep for TypeScript & React
The wrong defaults a capable model hits when pointing ast-grep at .ts/.tsx code — mostly cases where a rule silently matches nothing because the language or a node kind was guessed wrong. This skill assumes you already know ast-grep's rule mechanics (patterns, meta-variables, all/any/has/inside, constraints); it corrects only what TypeScript and React add on top.
For general ast-grep rule-writing mechanics, use the companion ast-grep skill.
When to Apply
- Writing an ast-grep pattern or YAML rule whose target is
.tsor.tsxcode - Searching for JSX elements, props, React hooks, imports, or TS type constructs
- Building a codemod that rewrites JSX or TypeScript (rename a component, strip
React.FC, migrate imports) - A rule "matches nothing" on TSX and you don't know why (usually the language or a node kind)
- Driving ast-grep programmatically from a JS/TS script via
@ast-grep/napi
First moves when a TS/React rule misbehaves
- Check the language. JSX-bearing files must run under
tsx, nevertypescript. This is the single most common cause of silent no-match. Seelang-tsx-for-jsx. - Debug the pattern's AST.
ast-grep run --pattern '<your pattern>' --lang tsx --debug-query=aston a real snippet shows the node kinds and revealsERRORnodes. Trust this over guessed kind names. - Wrap fragments. If the pattern is an attribute, prop, or type annotation, it needs
context+selector. Seectx-fragment-context-selector.
Rule Categories
| # | Category | Prefix | Covers |
|---|----------|--------|--------|
| 1 | Language Selection | lang | tsx-vs-typescript split, scanning .ts + .tsx, languageGlobs |
| 2 | Fragment Matching | ctx | context/selector for JSX attrs, props, type annotations |
| 3 | JSX Node Kinds | jsx | self-closing vs paired elements, attribute-value metavariables |
| 4 | TypeScript Constructs | ts | type-only imports, as casts, React.FC generics |
| 5 | Rewrites & Codemods | fix | re-emitting JSX metavars so children/props aren't dropped |
| 6 | Programmatic Use | napi | @ast-grep/napi Lang.Tsx, NapiConfig shape |
Quick Reference
1. Language Selection (lang)
lang-tsx-for-jsx— Use tsx for any JSX; typescript parses JSX as ERROR and matches nothinglang-scan-ts-and-tsx— Cover both.tsand.tsx;languageGlobsfor reuse (+ the<T>-cast caveat)
2. Fragment Matching (ctx)
ctx-fragment-context-selector— Wrap fragments (attrs, props, type annotations) in context/selector
3. JSX Node Kinds (jsx)
jsx-self-closing-vs-paired—<X/>and<X></X>are different kinds; match both withanyjsx-attribute-metavars— Metavariables must sit in a valid attribute-value position
4. TypeScript Constructs (ts)
ts-type-only-imports— Distinguishimport typeand inlinetypefrom value importsts-as-expression-casts— Match casts asas_expression, not angle bracketsts-generic-react-fc— StripReact.FCby targeting the type annotation
5. Rewrites & Codemods (fix)
fix-jsx-rewrite-completeness— Re-emit$$$PROPS/$$$CHILDRENor they're deleted
6. Programmatic Use (napi)
napi-lang-tsx-findall— Parse withLang.Tsx;findAlltakes aNapiConfig
How to Use
Read the individual reference file for the decision you're making — each is self-contained with a canonical example. references/_sections.md defines the categories; AGENTS.md is the full compiled index.
Related Skills
ast-grep— general ast-grep rule-writing mechanics (patterns, composition, constraints, testing). This skill layers TS/React specifics on top of it.