Skip to main content
Oxc is a Rust workspace with a modular architecture designed for high performance and maintainability.

Repository Structure

The repository is organized into several top-level directories:

crates/ - Core Functionality

The heart of Oxc. All Rust crates live here, organized by functionality:

Foundation Crates

  • oxc_allocator - Arena-based memory allocator for zero-copy operations
  • oxc_span - Source position tracking and text manipulation
  • oxc_syntax - JavaScript/TypeScript language definitions and token types
  • oxc_diagnostics - Error reporting with rich error messages
  • oxc_ast - Abstract Syntax Tree definitions and utilities

Parser and Analysis

  • oxc_parser - Hand-written recursive descent JS/TS parser
  • oxc_semantic - Semantic analysis, symbol resolution, scope analysis
  • oxc_cfg - Control Flow Graph construction

Tools

  • oxc_linter - Linting engine with 200+ rules (see Adding Rules)
  • oxc_formatter - Code formatting (Prettier-compatible)
  • oxc_transformer - Code transformation and transpilation (Babel-like)
  • oxc_minifier - Code size optimization and minification
  • oxc_codegen - AST to source code generation with source maps

Specialized Crates

  • oxc_isolated_declarations - TypeScript declaration file generation
  • oxc_language_server - LSP server for editor integration
  • oxc_traverse - AST traversal utilities
  • oxc_mangler - Identifier name mangling for minification
  • oxc_regular_expression - Regex parsing and analysis

Support Crates

  • oxc - Main crate that ties everything together
  • oxc_ast_visit - Generated visitor traits for type-safe AST traversal
  • oxc_macros - Procedural macros for code generation
Avoid editing any generated subdirectories. These are automatically created by running just ast.

apps/ - Application Binaries

Standalone applications built on top of the core crates:
  • apps/oxlint - Command-line linter with file discovery and parallel processing
  • apps/oxfmt - Command-line formatter (see apps/oxfmt/AGENTS.md for details)

napi/ - Node.js Bindings

NAPI (N-API) bindings for JavaScript integration:
  • napi/parser - Parser bindings for JavaScript tooling
  • napi/transform - Transformer bindings for bundlers
  • napi/minify - Minifier bindings
Tests are in each package’s test/ directory using Vitest.

npm/ - NPM Packages

Published npm packages including the compiled NAPI binaries and configuration schemas.

tasks/ - Development Tools

Development infrastructure and tooling:
  • tasks/coverage - Conformance testing against Test262, Babel, TypeScript
  • tasks/transform_conformance - Transformer-specific conformance tests
  • tasks/prettier_conformance - Formatter conformance against Prettier
  • tasks/rulegen - Linter rule generator
  • tasks/ast_tools - AST code generation
  • tasks/benchmark - Performance benchmarking
  • tasks/minsize - Minifier size tracking
  • tasks/website_* - Documentation generation for oxc.rs

editors/ - Editor Integrations

Editor extensions and plugins (e.g., VS Code extension).

Core Design Principles

1. Zero-Copy Architecture

Oxc uses an arena allocator (oxc_allocator) that enables zero-copy operations:
use oxc_allocator::Allocator;

let allocator = Allocator::default();
let ast = parser.parse(&allocator);
// All AST nodes live in the allocator's arena
Benefits:
  • No reference counting overhead (no Rc/Arc)
  • Better cache locality
  • Predictable performance
  • Simple memory management
Trade-offs:
  • Requires lifetime management
  • AST tied to allocator lifetime

2. Visitor Pattern

AST traversal uses automatically generated visitor traits:
impl<'a> Visit<'a> for MyVisitor {
    fn visit_function(&mut self, func: &Function<'a>) {
        // Custom logic here
        walk_function(self, func);
    }
}
Visitors are generated by procedural macros in oxc_ast_visit.

3. Distinct AST Types

Unlike ESTree, Oxc uses specific types instead of ambiguous nodes:
  • BindingIdentifier - Variable declarations and bindings
  • IdentifierReference - Variable references
  • IdentifierName - Property names and labels
This provides better type safety and follows the ECMAScript specification more closely.

4. Performance-First Design

  • Arena allocation for memory efficiency
  • Zero-copy strings using CompactString
  • Parallel processing at file level
  • Minimal allocations in hot paths
  • No garbage collection for predictable performance

Development Workflow

Typical Development Flow

1

Make changes to source code

Edit files in crates/ or apps/
2

Run formatting

just fmt
3

Run tests

just test
4

Update generated files (if needed)

just ast       # If you modified oxc_ast
just minsize   # If you modified oxc_minifier
just allocs    # If you modified oxc_parser
cargo lintgen  # If you added/modified linter rules
5

Run all checks

just ready

Working with Specific Components

Parser Development

# Run parser example
cargo run -p oxc_parser --example parser -- test.js

# Run conformance tests
just conformance parser

# Update allocation snapshots
just allocs

Linter Development

# Create new rule
just new-rule no-console eslint

# Run linter example
cargo run -p oxc_linter --example linter -- src/

# Regenerate rule registry
cargo lintgen

Transformer Development

# Run transformer tests
just test-transform

# Run conformance
cargo run -p oxc_transform_conformance -- --exec

# Filter specific tests
just test-transform --filter arrow

Formatter Development

# Run formatter example
cargo run -p oxc_formatter --example formatter -- test.js

# Run Prettier conformance
cargo run -p oxc_prettier_conformance

Key Locations

Finding Code

  • AST definitions: crates/oxc_ast/src/ast/
  • Linting rules: crates/oxc_linter/src/rules/<plugin>/
  • Parser entry: crates/oxc_parser/src/lib.rs
  • Lexer: crates/oxc_parser/src/lexer/
  • Semantic analysis: crates/oxc_semantic/src/
  • Tests: Co-located with source in tests/ subdirectories

Configuration Files

  • .rustfmt.toml - Rust formatting configuration
  • .clippy.toml - Clippy linter configuration
  • justfile - Development commands
  • Cargo.toml - Workspace configuration
  • oxlintrc.json - Oxlint configuration for the project itself

Conventions

Memory Management

  • Use oxc_allocator::Allocator for AST allocations
  • Use Box for heap allocations outside the arena
  • Avoid Rc/Arc in hot paths

Error Handling

  • Use oxc_diagnostics::OxcDiagnostic for user-facing errors
  • Include source spans for diagnostic context
  • Provide helpful error messages with suggestions

Performance

  • Profile changes that affect hot paths
  • Minimize allocations in loops
  • Use CompactString for short strings
  • Prefer borrowed data over cloning

Testing

  • Write tests co-located with source code
  • Use snapshot tests for complex output
  • Run conformance tests for correctness
  • See Testing Guide for details

Dependencies

Core Dependencies

  • Rust: MSRV 1.91 (N-2 policy)
  • Node.js: For NAPI bindings and npm packages
  • pnpm: Node.js package manager

Key Rust Crates

  • compact_str - Efficient string handling
  • rustc-hash - Fast hash maps
  • serde - Serialization
  • insta - Snapshot testing

Next Steps

Build docs developers (and LLMs) love