ast-types

An Esprima-compatible implementation of the Mozilla JS Parser API, with typed AST builders and visitors.

Library
npm
v0.14.2
1,173stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
41/100Fair
Development Activity0
Maintenance0
Community76
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
67/100Good
Architecture78
Code Quality70
Innovation65
Learning Curve55

ast-types is a JavaScript library that defines a typed, extensible hierarchy of JavaScript AST node types compatible with the Mozilla Parser API (as used by Esprima, Acorn, and Babel’s parser). It generates typed builder functions (e.g. b.functionDeclaration(…)) for constructing AST nodes programmatically, a namedTypes namespace for runtime type-checking and validation of node shapes, and a Visitor/PathVisitor API for traversing and transforming ASTs with full path context (parent, scope, and replace/prune operations).

Because it models the type hierarchy explicitly (including extension modules for JSX, Flow, TypeScript, and various ES-proposal syntaxes) rather than treating the AST as untyped JSON, ast-types underlies tooling that needs to reliably construct, validate, or mutate JavaScript/TypeScript syntax trees — most notably recast (source-preserving code transformation) and jscodeshift (codemod tooling), both maintained by the same author.

What You Get

  • Typed builder functions (via the builders namespace) for constructing every AST node type in the supported grammar
  • A namedTypes namespace with runtime type-checking (.check()) and field introspection for validating AST node shapes
  • A Visitor/PathVisitor API for traversing an AST with NodePath context (parent access, scope tracking, replace/prune mutation)
  • Extension modules (def/jsx, def/flow, def/typescript, def/es-proposals, def/babel) layering JSX, Flow, TypeScript, and stage-N syntax onto the core ES grammar
  • A fork() function to compose a custom subset of type-definition modules for a narrower or extended grammar

Common Use Cases

  • Building codemods that programmatically rewrite JavaScript/TypeScript source across a codebase (jscodeshift)
  • Implementing source-preserving code transformation tools that reprint only the AST nodes that changed (recast)
  • Writing custom Babel-adjacent tooling that needs to construct or validate AST nodes with type safety
  • Building linters, code generators, or static-analysis tools that traverse and mutate a JS/TS AST

Under The Hood

Architecture The core is a type-definition system (src/types.ts, src/shared.ts) where each grammar module under src/def/ (core.ts, es2015 through es2022, jsx.ts, flow.ts, typescript.ts, babel.ts, esprima.ts) declares node types, their fields, and supertype relationships via a Def builder API; src/main.ts calls fork() with a chosen list of def modules to assemble a concrete type hierarchy, from which src/gen/ generates the namedTypes, builders, and visitor namespaces consumed by library users, while src/path.ts, src/node-path.ts, and src/path-visitor.ts implement the path-aware traversal and mutation layer used during codemods.

Tech Stack Written in TypeScript (~16,600 lines across src/), with a code-generation step (script/gen-types.ts, run via ts-node) that produces the concrete builders/namedTypes/visitor modules under src/gen/ from the declarative type definitions, compiled to CommonJS for publishing.

Code Quality The project has a dedicated test suite under src/test (api.ts, ecmascript.ts, flow.ts, typescript.ts, type-annotations.ts, perf.ts) run via script/run-tests.sh, exercising the generated builders/visitors against real ECMAScript, Flow, and TypeScript syntax fixtures; as a widely-depended-upon foundation for recast and jscodeshift, correctness here has broad downstream impact, though the project has seen no tagged npm release since 2020 despite later repository commits.

API Design The typed-builder-plus-visitor design (b.identifier(‘x’), n.FunctionDeclaration.check(node), PathVisitor.fromMethodsObject({…})) closely mirrors the shape of the Mozilla Parser API/ESTree spec that most JS tooling already assumes, which keeps the learning curve low for anyone who has used Babel or Esprima-family tools, though the extension-module/fork() composition model requires understanding which def modules are active to know what node types are available.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search