- Upgraded OXC toolchain from 0.117 to 0.129 — 12 releases of parser, transformer, minifier, and codegen improvements.
- Upgraded OXC formatter from crates_v0.117.0 to crates_v0.129.0.
- Upgraded OXC linter from crates_v0.117.0 to crates_v0.129.0 (oxc_linter 1.62.0).
- Upgraded oxc_sourcemap from 6 to 6.1.
OXC.bundle/2accepts filesystem entry paths, e.g.OXC.bundle("src/main.ts", cwd: project_dir), alongside virtual{filename, source}projects.- Bundle resolver options for Rolldown:
:conditions,:main_fields, and:modules. - Bundle output options for Rolldown:
:exportsand:preserve_entry_signatures.
- Removed the binding-level bare import auto-externalization pass; Rolldown now handles unresolved externals directly.
OXC.codegen/1/codegen!/1— generate JavaScript source from ESTree AST maps via OXC's code generator. Proper operator precedence, formatting, and semicolons. Roundtrips withparse/2.OXC.bind/2— substitute$placeholdersin a parsed AST with identifiers, literals (including recursive maps/lists → JS objects/arrays), parsed expressions, or raw AST nodes.OXC.splice/3— expand a$placeholderstatement, object property, or array element into a list of nodes. Strings are auto-parsed as JS.:externaloption forOXC.bundle/2— list of bare specifiers to preserve asimportstatements in the output. Merged with auto-detected ESM externals.
- Enable JSX parsing for
.jsfiles in formatter, matching oxfmt CLI behavior. Fixes formatting failures on projects using JSX in.jsfiles (e.g. Plausible Analytics).
OXC.Format— Prettier-compatible JS/TS formatter via oxfmt (~30× faster than Prettier). Separateoxc_fmt_nifRust NIF crate. All oxfmt options supported:print_width,tab_width,use_tabs,semi,single_quote,jsx_single_quote,trailing_comma,bracket_spacing,bracket_same_line,arrow_parens,end_of_line,quote_props,single_attribute_per_line,object_wrap,experimental_operator_position,experimental_ternaries,embedded_language_formatting,sort_imports,sort_tailwindcss.OXC.Lint.run!/3— bang variant that raisesOXC.Erroron parse errors.
OXC.Format.run!/3raisesOXC.Errorinstead ofRuntimeError.
OXC.Lint.run/3— lint JS/TS source with oxlint's 650+ built-in rules via a Rust NIF. Supports all oxlint plugins (react, typescript, unicorn, import, jsdoc, jest, vitest, jsx-a11y, nextjs, promise, node, vue) and configurable rule severities.OXC.Lint.Rulebehaviour — write custom lint rules in Elixir that operate on the parsed ESTree AST. Rules useOXC.walk/2,OXC.collect/2, orOXC.postwalk/3for traversal and return diagnostics with spans.- Built-in and custom rules run together in a single
OXC.Lint.run/3call.
OXC.transform_many/2— transform multiple files in parallel via a Rust rayon thread pool. Single NIF call, no BEAM scheduling overhead. 6.8x faster than sequentialtransform/3on 2000 files.
- Fix
parse/2hitting serde_json recursion limit on deeply nested ASTs (e.g. large bundled output from Vue + reka-ui). Uses streaming deserializer with unbounded depth.
- AST
:typeand:kindvalues are now snake_case atoms instead of strings."ImportDeclaration"→:import_declaration,"const"→:const, etc. Migration: update all pattern matches from%{type: "ImportDeclaration"}to%{type: :import_declaration}. - All error tuples now return
{:error, [%{message: String.t()}]}consistently. Previouslytransform,minify,imports, andbundlereturned{:error, [String.t()]}. - Bang functions (
parse!,transform!,minify!,bundle!, etc.) now raiseOXC.Errorinstead ofRuntimeError. The exception has an:errorsfield with the structured error list.
OXC.collect_imports/2— analyze imports with type info (:static/:dynamic), kind (:import/:export/:export_all), and byte offsets. Powered by a Rust NIF using OXC's visitor pattern.OXC.rewrite_specifiers/3— rewrite import/export specifiers in a single pass without Elixir-side AST walking.:preambleoption forbundle/2— inject code at the top of the IIFE function body.:treeshakeoption forbundle/2— enable tree-shaking (default:false).walk/2,postwalk/2,postwalk/3now accept a list of nodes at the root level.OXC.Errorexception module.
collect/2uses a recursive accumulator instead of creating an ETS table per call.to_snake_atomusesMacro.underscore/1instead of hand-rolled regex.ImportInfouses#[derive(NifMap)]instead of a manualEncoderimpl.@type asttightened to%{required(:type) => atom(), optional(atom()) => any()}.patch_string/2deduplication behavior is now documented.- Rust NIF split from a single 800-line
lib.rsintoparse.rs,imports.rs,bundle.rs,options.rs,error.rs. - Import collector rewritten with
oxc_ast_visit::Visittrait (~50 lines) replacing a hand-rolled 250-line AST walker. - Bundle chunk selection no longer falls through to arbitrary chunks.
- Fix absolute temp dir paths leaking into
#regioncomments in bundled output
- Added
:formatoption tobundle/2— supports:iife(default),:esm, and:cjsoutput formats
OXC.bundle/2now requiresentry: "..."to identify the bundle entry module. Migration: changeOXC.bundle(files)toOXC.bundle(files, entry: "main.ts").
OXC.bundle/2now uses Rolldown/OXC for bundling.- Internal Rustler boundary code for
parse,transform,minify, andbundlewas simplified with serde-based term encoding/decoding.
- Handle
export default <expression>in bundler — emitsvar _default = <expr>instead of dropping the expression. Fixes Vue SFC compiled output losing the component object.
- Fix
export { local as default }producingvar default = local(syntax error). The bundler's alias emitter now uses_defaultfor the reserved worddefault.
- (yanked — fix was incomplete)
- Handle circular dependencies in bundler's topological sort — modules in a cycle are appended in sorted order instead of raising an error. Enables bundling Vue, Reka UI, and other frameworks with circular imports.
- Initial precompiled NIF release (aarch64-apple-darwin, x86_64-apple-darwin, x86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu, x86_64-unknown-linux-musl)
- Move to elixir-volt org
OXC.bundle/2— bundle multiple JS/TS modules into a single IIFE with topological sorting and import resolutionOXC.imports/2— extract import specifiers from sourceOXC.postwalk/3— AST traversal with accumulator for source patchingOXC.patch_string/2— apply byte-offset patches- Compile-time replacements via
:defineoption - Source map support in bundle and minify