AST Structure
Oxc’s Abstract Syntax Tree (AST) is the core data structure representing JavaScript and TypeScript code in a structured, programmatic format. Understanding the AST is essential for working with Oxc’s parser, transformer, linter, and other tools.Overview
The AST provides comprehensive node definitions that support the full spectrum of JavaScript and TypeScript syntax, including JSX. Unlike many JavaScript tools that use the ESTree specification, Oxc takes a different approach focused on clarity and type safety.Key Design Principles
Explicit Identifier Types
One of the most important differences from ESTree is how Oxc handles identifiers. Instead of a genericIdentifier node, Oxc provides three distinct types that align closely with the ECMAScript specification:
BindingIdentifier
Used for variable declarations and bindings
IdentifierReference
Used for variable references
IdentifierName
Used for property names and labels
This distinction eliminates a major source of confusion in AST-based tools. With ESTree’s generic
Identifier, developers must constantly check context to understand what kind of identifier they’re working with. Oxc’s explicit types make this immediately clear.Node Structure Example
Here’s how these identifier types are defined in Oxc:Notice that
BindingIdentifier has a symbol_id field, while IdentifierReference has a reference_id field. These are populated during semantic analysis and link identifiers to their declarations and uses.Specialized Literal Types
Similarly, Oxc replaces ESTree’s genericLiteral node with specific types:
BooleanLiteral-trueorfalseNumericLiteral-42,3.14,0xFFBigIntLiteral-123nStringLiteral-"hello"RegExpLiteral-/pattern/flagsNullLiteral-nullTemplateLiteral-`hello ${world}`
Precise Assignment Targets
TheAssignmentExpression.left field uses the specific AssignmentTarget type instead of a generic Pattern, making it clear what can appear on the left side of an assignment:
AST Node Anatomy
Every AST node in Oxc includes:- Node ID: A unique identifier for the node, used for efficient lookups
- Span: Source position information (start and end byte offsets)
- Node-specific fields: The data that defines this particular node type
Working with the AST
Parsing Code into an AST
Here’s how to parse JavaScript/TypeScript code into an AST:All AST nodes are allocated in the
Allocator arena. This is key to Oxc’s performance. See Allocator documentation for details.Inspecting AST Structure
You can debug-print the AST to see its structure:const x = 42;, you’ll see something like:
Traversing the AST
To systematically traverse the AST, use the visitor pattern:Expression and Statement Hierarchies
Oxc’s AST uses Rust enums to represent the different types of expressions and statements:All variants are wrapped in
Box<'a, T> where 'a is the lifetime of the allocator. This allows the AST to reference nodes without copying.Memory Management
All AST nodes are allocated in an arena allocator and have the lifetime'a tied to that allocator:
Field Ordering
Fields in AST nodes follow ECMAScript evaluation order. This ensures that when you traverse fields in declaration order, you’re processing them in the same order JavaScript would execute them. For example, in aForStatement:
Integration with Semantic Analysis
The AST alone doesn’t include semantic information like scope or symbol resolution. That’s added by the semantic analyzer:Differences from ESTree
Key differences between Oxc AST and ESTree:| Feature | ESTree | Oxc |
|---|---|---|
| Identifiers | Generic Identifier | BindingIdentifier, IdentifierReference, IdentifierName |
| Literals | Generic Literal | BooleanLiteral, NumericLiteral, StringLiteral, etc. |
| Assignment targets | Generic Pattern | Specific AssignmentTarget enum |
| Memory model | Reference counted | Arena allocated with lifetimes |
| Node IDs | Not included | Every node has a NodeId |
| Spans | Optional | Required on every node |
Next Steps
Allocator
Learn about arena allocation and memory management
Visitor Pattern
Learn how to traverse and transform AST nodes
Semantic Analysis
Learn about scope resolution and symbol tables
Parser API
Explore the parser API documentation