Parser Architecture
Oxc maintains its own AST and parser, which is by far the fastest and most conformant JavaScript and TypeScript (including JSX and TSX) parser written in Rust.
As the parser often represents a key performance bottleneck in JavaScript tooling, any minor improvements can have a cascading effect on our downstream tools. By developing our parser, we have the opportunity to explore and implement well-researched performance techniques.
AST Design Philosophy
While many existing JavaScript tools rely on [estree] as their AST specification, a notable drawback is its abundance of ambiguous nodes. This ambiguity often leads to confusion during development with [estree].
The Oxc AST differs from the [estree] AST by removing ambiguous nodes and introducing distinct types. For example, instead of using a generic [estree] Identifier, the Oxc AST provides specific types such as BindingIdentifier, IdentifierReference, and IdentifierName.
This clear distinction greatly enhances the development experience by aligning more closely with the ECMAScript specification.
AST Node Types
// Instead of generic Identifier
pub struct BindingIdentifier<'a> {
pub span: Span,
pub name: Atom<'a>,
}
pub struct IdentifierReference<'a> {
pub span: Span,
pub name: Atom<'a>,
pub reference_id: Cell<Option<ReferenceId>>,
}
pub struct IdentifierName<'a> {
pub span: Span,
pub name: Atom<'a>,
}
``````rust
use oxc_allocator::Allocator;
// All AST nodes are allocated in this arena
let allocator = Allocator::default();
let ast_node = allocator.alloc(Expression::NumericLiteral(
allocator.alloc(NumericLiteral { value: 42.0, span: SPAN })
));
``````rust
// Strings ≤ 24 bytes are stored inline (no heap allocation)
let short_name = CompactString::from("variableName"); // Stack allocated
let long_name = CompactString::from("a_very_long_variable_name_that_exceeds_limit"); // Heap allocated
``````rust
// Phase 1: Parse to AST
let parser_result = Parser::new(&allocator, &source_text, source_type).parse();
// Phase 2: Semantic analysis
let semantic_result = SemanticBuilder::new()
// Enable additional syntax checks not performed by the parser
.with_check_syntax_error(true)
.build(&parser_result.program);
``````rust
// Meaningful error messages with source location
pub struct OxcDiagnostic {
pub message: String,
pub span: Span,
pub severity: Severity,
pub help: Option<String>,
}