The Four Pillars
1. Zero-Copy Architecture
The zero-copy principle is the most critical aspect of Oxc’s performance. By minimizing data copying and allocation overhead, Oxc achieves performance that is often 10-100x faster than comparable tools.
Arena-Based Allocation
At the heart of Oxc’s zero-copy architecture is the arena allocator (oxc_allocator). All AST nodes for a compilation unit are allocated in a single memory arena.
How It Works
Benefits
No Reference Counting
Eliminates
Rc/Arc overhead and atomic operations from hot pathsCache Locality
Contiguous allocation improves CPU cache utilization
Fast Deallocation
Entire arena dropped at once - no individual node deallocation
Structural Sharing
Enables efficient sharing of AST subtrees
String Optimization
Short strings are inlined usingCompactString:
- Strings ≤ 24 bytes on 64-bit systems are stored inline
- No heap allocation for small strings
- Transparent upgrade to heap allocation when needed
- Single allocation per string
- No copying during AST operations
- Lifetime tied to arena
Lifetime Management
While this requires explicit lifetime annotations, it provides compile-time guarantees of memory safety without runtime overhead.
Borrowed References in Hot Paths
Visitors operate on borrowed references (&Node<'a> or &mut Node<'a>), never owned values:
- No allocation during traversal
- No cloning of nodes
- Zero-copy reads and modifications
Performance Impact
Measured improvements from arena allocation:- 10-50% faster parsing compared to
Rc/Arc-based approaches - Predictable memory usage - single large allocation vs many small ones
- Faster garbage collection - single
dropinstead of thousands
2. Visitor Pattern
Oxc uses the visitor pattern for AST traversal, implemented through automatically generated traits via procedural macros.Generated Visitor Traits
Oxc provides two visitor traits:Visit- Immutable traversal (read-only analysis)VisitMut- Mutable traversal (AST transformation)
oxc_ast_macros).
How It Works
Visitor Generation Process
Benefits
Type Safety
Compiler enforces correct usage - impossible to miss fields or use wrong types
Zero Boilerplate
Only implement methods for nodes you care about
Efficient Dispatch
Static dispatch - no virtual function overhead
Consistent Traversal
All tools traverse AST in same order
Traversal Order
Visitors traverse AST fields in the same order they are defined in the AST types, which follows the “Evaluation order” from the ECMAScript specification.
VariableDeclaration:
- Visit
kind(const/let/var) - Visit
declarations(array of declarators) - For each declarator: pattern → initializer
Alternative: Traverse
For more complex transformations, useoxc_traverse:
- Provides
Traversetrait with enter/exit hooks - Access to traversal context
- Ability to insert/remove nodes during traversal
- Scope-aware transformations
Visitor Use Cases
| Tool | Visitor Type | Purpose |
|---|---|---|
| Linter | Visit | Read-only analysis to detect issues |
| Semantic | Visit | Build symbol tables and scopes |
| Transformer | Traverse | Modify AST with scope awareness |
| Minifier | Traverse | Optimize and transform code |
| Codegen | Manual | Generate code (no visitor needed) |
3. Shared Infrastructure
Common functionality is shared across all components to ensure consistency and avoid duplication.Shared Foundation Crates
oxc_diagnostics: Unified Error Reporting
Purpose: Consistent error messages across all tools Features:- Source code snippets with highlighting
- Multiple output formats (human-readable, JSON)
- Severity levels (error, warning, info)
- Related information and suggestions
- LSP-compatible diagnostics
oxc_span: Unified Position Tracking
Purpose: Consistent source position representation Key Decisions:- Uses
u32instead ofusizefor memory efficiency - Byte-based offsets (not character-based)
- Supports UTF-8 correctly
- Compact representation (8 bytes on 64-bit systems)
- Fast comparison and operations
- Consistent across all components
- Enables efficient source map generation
oxc_syntax: Language Definitions
Purpose: Shared syntax knowledge Contents:- Token definitions
- Keyword mappings
- Operator precedence
- Node, reference, scope, and symbol flags
- Language feature flags
- Ensures parser and semantic analyzer agree on syntax
- Single source of truth for language features
- Easier to add new language features
Benefits of Sharing
Consistency
All tools report errors in the same format and use the same definitions
Maintainability
Changes to shared infrastructure benefit all tools
Smaller Binary
Code sharing reduces final binary size
Correctness
Single source of truth reduces bugs from inconsistencies
4. Modular Composability
Oxc is not a monolithic tool - it’s a collection of independent, reusable components that can be composed in different ways.
Independent Crates
Each major component is published as an independent crate:Composition Patterns
Pattern 1: Parse Only
Pattern 2: Parse + Semantic
Pattern 3: Full Pipeline
Use Cases
- AST Analysis
- Type Checking
- Build Tool
- Documentation
Need: Just parse and analyze ASTComponents:
oxc_parser + oxc_allocator + oxc_astExample: ESLint plugin that analyzes code structureCargo Features
Components expose cargo features for fine-grained control:serialize- Enable ESTree JSON serializationcfg- Include control flow graphjsdoc- Parse JSDoc commentslinter- Enable linter-specific optimizations
Benefits
Pay for What You Use
Only include components you need - smaller binaries
Flexibility
Compose tools in novel ways for custom use cases
Independent Evolution
Components can evolve independently with semantic versioning
Easy Integration
Drop individual components into existing projects
Principles in Action: Linter Example
Let’s see how all four principles work together in the linter: Step by Step:- Zero-Copy: Parse file into arena-allocated AST
- Shared Infrastructure: Use
oxc_spanfor positions,oxc_diagnosticsfor errors - Modular: Parser and semantic analyzer are independent crates
- Visitor: Each lint rule implements visitor pattern
- Zero-Copy: Rules operate on borrowed AST references
- Shared Infrastructure: All rules produce consistent diagnostics
Design Trade-offs
Arena Allocation
| Benefit | Trade-off |
|---|---|
| 10-50% faster performance | Requires lifetime annotations |
| Simpler memory management | Less flexible memory patterns |
| Better cache locality | Cannot easily share nodes between arenas |
Visitor Pattern with Macros
| Benefit | Trade-off |
|---|---|
| Type-safe traversal | Longer compile times (proc macros) |
| Zero boilerplate | Learning curve for contributors |
| Compile-time guarantees | More complex error messages |
Shared Infrastructure
| Benefit | Trade-off |
|---|---|
| Consistency across tools | Changes affect all components |
| Reduced duplication | More careful API design required |
| Smaller binaries | Tighter coupling between crates |
Modular Composability
| Benefit | Trade-off |
|---|---|
| Flexible composition | More crates to manage |
| Smaller dependencies | Version compatibility complexity |
| Independent evolution | Need to maintain stable APIs |
Related Reading
Architecture Overview
Comprehensive overview of Oxc’s architecture and components
Performance
Deep dive into performance implementation and benchmarks