Oxc v0.137 Teaches the Minifier to Treeshake Pure Typed Arrays and Set/Map Literals, Lands an Incremental Scoping Refresh, and Fixes a React Compiler Edge Case

Oxc v0.137 Teaches the Minifier to Treeshake Pure Typed Arrays and Set/Map Literals, Lands an Incremental Scoping Refresh, and Fixes a React Compiler Edge Case

lschvn

Oxc release crates_v0.137.0, published on June 18, 2026, ships two new minifier treeshaking passes, a long-running incremental scoping refresh, a friendly parser error for adjacent JSX elements, and a React Compiler bug fix for computed-key imports. The release also carries two breaking changes to the ESTree config API and the densest perf patch list in the project so far: eleven performance entries across the parser, the minifier, the mangler, the transformer, and the React Compiler.

This is the first crates release since v0.135 on June 8 and the second since Bun's native React Compiler integration merged into oven-sh/bun on June 20. Bun's port pulls the upstream facebook/react Rust workspace directly, so the Oxc changes here still flow back to the upstream compiler through Meta's port and the react_compiler_oxc adapter that other bundlers are picking up.

The headline: two new minifier treeshaking passes

The new pass that users will feel first is treeshake pure typed arrays and Set/Map array literals (#23469, Dunqing). The pre-v0.137 minifier could already treeshake a const x = [1, 2, 3] whose contents were pure, but it stopped at the typed-array boundary: a new Uint8Array([1, 2, 3]) whose bytes were unused stayed in the output, as did a new Map([["a", 1], ["b", 2]]) whose entries were never read. The v0.137 pass recognizes those constructors, walks the inner array literal, and treats it the same way the regular array-literal pass does: pure + unused => drop.

The complement is inline const value for read-only vars (#22593, also Dunqing). The pre-v0.137 minifier would only inline a const binding if the binding was used exactly once; v0.137 inlines the value at every use site when the binding is a const and the value is treated as read-only by the type-aware analysis. That gives the rest of the minifier (constant folding, conditionals, return-statement simplification) a chance to fold the result. The PR description walks through a worked example: a const FOO = computeFoo() followed by a downstream if (FOO > 0) collapses to the inlined comparison when computeFoo is a pure literal-returning arrow, and to a constant-condition branch when it is a pure constant-returning arrow.

Both passes are gated behind CompressOptions flags, off by default in v0.137. The release notes are explicit that the default CompressOptions in oxc_minifier v0.137 matches v0.136, so the gains are opt-in.

The biggest perf change: incremental scoping refresh

The single largest perf change in v0.137 is Incremental scoping refresh, delete LiveUsageCollector (#23197, Dunqing). LiveUsageCollector was the only structure in oxc_minifier that walked the full scope tree on every minifier pass to figure out which symbols were still in use. The incremental scoping refresh splits that into per-statement updates and skips the full walk when no downstream change invalidates the cache.

Dunqing's PR description is direct: LiveUsageCollector was the largest constant cost in large minifier runs, and the only pass in oxc_minifier that still ran in O(scope) on every entry to a function body. Removing it deletes the only minifier internal that needed the full scope tree on every entry, and the rest of the minifier can now use a cheaper per-statement refresh. The release notes do not include a number, but the related perf patches in the same release tell the same story:

  • Mangler: compile slot sort once instead of per CAPACITY (#23577, Boshen)
  • Parser: reduce code bloat from verify_modifiers monomorphization (#23576, Boshen)
  • ESTree: remove pointless mem::take (#23572, overlookmotel)
  • Transformer: pre-size statement vecs in TS enum & namespace lowering (#23516, Yunfei He)
  • Minifier: compute template-literal inline checks in a single pass (#23467, Yunfei He)
  • Semantic, mangler, minifier: fix Semantic::stats node count and reuse stats in mangler builds (#23352, Boshen)
  • Minifier: evaluate ternary branches once in minimize_conditional_expression (#23479, Yunfei He)
  • Transformer: pre-size JSX props vec to attribute count (#23466, Yunfei He)
  • React Compiler: borrow binding names in prefilter instead of allocating (#23471, Yunfei He)

The semantic/mangler/minifier fix in #23352 is the one that the other perf entries build on: Semantic::stats previously returned node counts that did not match what the mangler was about to compute, so the mangler had to redo the work. The fix makes the counts match, and the rest of the release can reuse them. v0.137 is the first release where the semantic/mangler/minifier pipeline is consistent about stats.

Two breaking changes to the ESTree config

The two breaking changes are both in the optional ESTree compatibility layer, not the compiler itself. Make whether to include TS fields a runtime option (#23574, overlookmotel) moves the decision of whether the ESTree AST exposes TypeScript-specific fields (TS annotations, type parameters, TS-only nodes) from a Cargo build feature to a runtime option on the ESTree builder. ESTree config use methods not consts (#23573, overlookmotel) replaces public const items on the ESTree config struct with methods, so call sites change from config.include_ts_fields to config.include_ts_fields().

Downstream crates that build a custom ESTree AST have to update their config calls. The compiler itself, the parser, the transformer, the minifier, and the React Compiler are all unchanged by the ESTree rework. The ESTree layer is the one that lets Oxc emit an AST that matches the ESTree spec, which is what tools like Rollup, esbuild, and webpack's acorn-based loader chain consume.

The React Compiler entries

The two React Compiler entries are the most relevant to the previous day's news. Keep imports referenced only by a computed key (#23586, Boshen) fixes a real correctness gap in the React Compiler's import tracking: an import whose only use is as the right-hand side of a computed key (for example, obj[SomeImport] where SomeImport is a renamed default import) was being dropped, which compiled away to undefined behaviour in the React Compiler's HIR. The fix keeps the import alive whenever a computed key resolves to it.

Borrow binding names in prefilter instead of allocating (#23471, Yunfei He) is a perf entry, not a fix. The prefilter is the React Compiler's first pass over a function body to decide whether the body is a candidate for compilation; the prefilter used to allocate a String per hit, which on a large React codebase with many components adds up. The borrow removes the allocation.

These changes go into the upstream facebook/react Rust workspace, not just the Oxc fork. Bun's native React Compiler integration ports the upstream compiler/crates/ workspace directly, so the v0.137 React Compiler entries will be in the next Bun sync. Oxlint and oxfmt pull the latest crates on their weekly release cadence, and the oxlint 1.70 release two weeks ago was the first to ship the upstream port of the React Compiler as a Rust crate; v0.137 is the second crates release to carry React Compiler perf and correctness work.

The parser UX work

Two parser changes are aimed at developer ergonomics rather than raw perf. Parser: add friendly error for adjacent JSX elements (#23378, sapphi-red) replaces the cryptic "unexpected token" error that the parser used to emit when two adjacent JSX elements (e.g. <a /><b /> at the start of a file without an explicit fragment wrapper) failed to parse, with a message that names the problem and points at the offending token. Parser: treat a line comment after ':' as leading, not trailing (#23515, Dunqing) fixes a long-standing comment-attribution bug where a // foo comment after a : was attached to the previous token instead of the next one, which made source maps wrong in some cases.

Two minifier correctness fixes worth calling out

The two minifier bug fixes are small but the kind of thing that bites in production:

  • Minifier: keep Object introspection calls on a possible Proxy (#23483, Dunqing) stops the minifier from dropping Object.keys(obj), Object.values(obj), Object.entries(obj), and Object.getOwnPropertyDescriptor(obj, key) when obj could be a Proxy, because the call could invoke the proxy's ownKeys or getOwnPropertyDescriptor trap and return arbitrary values.
  • Minifier: keep new Map/WeakSet/WeakMap with a string argument (#23470, Dunqing) stops the minifier from dropping a new Map([["a", 1]]) whose literal argument is a string-keyed array of pure entries, because the constructor's iteration order matters and the minifier was treating it as a no-op.

Both are in the same family as the new treeshake pure typed arrays pass, but in reverse: the new pass is an opt-in expansion of what the minifier can prove is safe to drop, and the two fixes are corrections to places where the pre-v0.137 minifier was over-aggressive.

What v0.137 does not change

The release does not change the parser or minifier defaults, the transformer surface, or the React Compiler's public API. The breaking changes are confined to the optional ESTree config layer. The oxc_ast, oxc_parser, oxc_semantic, oxc_transformer, oxc_minifier, oxc_mangler, and oxc_react_compiler crate APIs are all backwards-compatible with v0.136. The next oxlint and oxfmt apps release on the weekly Monday cadence will pick up the v0.137 perf wins in the parser, minifier, and React Compiler crates, plus the LiveUsageCollector removal in oxc_minifier.

The release is also the second to carry the Oxc team's new convention of breaking the body into emoji-headed sections (💥 BREAKING CHANGES, 🚀 Features, 🐛 Bug Fixes, ⚡ Performance, 📚 Documentation), which Oxc v0.135 introduced. The pattern matches the Biome changelog format and the Vite 8 release notes, and makes it easier to scan a release for what matters to your code at a glance.

Frequently Asked Questions

Sakana Fugu Wraps a Multi-Agent Orchestrator Behind a Single API, Claims Frontier Parity With Fable and Mythos

Sakana AI launched Fugu on June 22, 2026, a multi-agent orchestration system delivered as a single OpenAI-compatible API. Two models, Fugu and Fugu Ultra, coordinate a pool of closed-source LLMs using learned orchestration from two ICLR 2026 papers (TRINITY and Conductor). Fugu Ultra posts benchmark scores competitive with Anthropic's Fable 5 and Mythos Preview, but the release draws sharp criticism over cost transparency, closed-source dependencies, and benchmark methodology.

Astro 7.0.0 Stable Ships Vite 8, Makes the Rust Compiler Default, Adds a Background Dev Server for AI Coding Agents, and Promotes Route Caching, Advanced Routing, and Sätteri to First-Class

Astro 7.0.0, published on 2026-06-22, lands the 7.0 stable branch after ten weeks of beta. The headline changes: a Vite 8 upgrade, the Rust-based Astro compiler as the default (the Go compiler is removed), the Sätteri Markdown pipeline as the default (remark/rehype moves out of the default install), advanced routing promoted from experimental (with src/fetch.ts as the new default entrypoint), route caching promoted from experimental (top-level cache and routeRules, with cacheNetlify() and cacheVercel() providers landing in the same release), a background dev server mode designed for AI coding agents (astro dev --background, .astro/dev.json lockfile, astro dev stop|status|logs), compressHTML: 'jsx' as the new default, the @astrojs/db package removed, and every official integration bumped a major version (vue 7, react 6, svelte 9, preact 6, solid-js 7, vercel 11, netlify 8, node 11). create-astro@5.1.0, shipped in the same release wave, now writes an AGENTS.md file into every new project with a CLAUDE.md symlink pointing at it.

Related articles

More coverage with overlapping topics and tags.

Oxlint v1.71 and Oxfmt v0.56 Ship the v0.137 Crates Wins, Land 18 New Linter Rules, and Tame React Lifecycle Traversal with a Streamed-Iterator Refactor
tooling

Oxlint v1.71 and Oxfmt v0.56 Ship the v0.137 Crates Wins, Land 18 New Linter Rules, and Tame React Lifecycle Traversal with a Streamed-Iterator Refactor

Oxlint apps_v1.71.0 and oxfmt apps_v0.56.0, both published on 2026-06-22, close out the v0.137 crates cycle. Oxlint v1.71 picks up the new treeshaking pure typed arrays minifier pass (#23469), the prefer-query-selector compound selector fix, 28 lint bug fixes (most of them Yunfei He's fixer-rewrite work), 13 performance entries anchored on a bucketed rule dispatch refactor (#23450, #23452, #23482-#23486, #23489, #23492), and the oxlint Tokio-on-LSP-only startup (#23447). Oxfmt v0.56.0 ships 9 bug fixes (CRLF normalization for `// @ts-ignore` suppressed text in #23701 and #23702, the member-chain panic fix #23698, the default-export-with-type-cast preservation #23697) and 3 formatter performance entries that remove arena copies on bigint, numeric-literal, and string-literal text. v1.71 is the first apps release since v1.70.0 on 2026-06-15, and the last one before the v0.138 crates release that will land on Monday 2026-06-29.
Bun Integrates the React Compiler Directly Into Its Bundler, Roughly 20x Faster Than the Babel Plugin
tooling

Bun Integrates the React Compiler Directly Into Its Bundler, Roughly 20x Faster Than the Babel Plugin

PR #32504, merged into oven-sh/bun on June 20, 2026, turns the upstream React Compiler Rust port into a built-in `bun build` transform behind `--react-compiler` and `Bun.build({ reactCompiler: true })`. Bun ports the upstream `facebook/react` `compiler/crates/` workspace directly into a single `src/react_compiler/` crate (~62k LOC) instead of going through Babel, SWC, or Oxc, and on a large React codebase (around 860 components, 1400 memo slots) the compiler pass runs in 465 ms versus 9.15 s for the Babel plugin. The feature is experimental, off by default, and ships with `reactCompilerOutputMode` (client or ssr) and a `scripts/sync-react-compiler.sh` re-sync helper.
Astro 7.0.0-beta.6 Stabilizes Route Caching and Promotes JSX Whitespace Compression to Default
tooling

Astro 7.0.0-beta.6 Stabilizes Route Caching and Promotes JSX Whitespace Compression to Default

Astro 7.0.0-beta.6 (June 19, 2026) promotes the experimental route caching API to top-level stable, dropping the experimental.cache and experimental.routeRules flags in favor of a new top-level cache config and a cache helper. Beta.5 (June 18) made 'jsx' the default compressHTML mode, changing the rendered output of every site that relied on the legacy whitespace preservation. Beta.6 also pulls in @astrojs/markdown-satteri 0.3.1-beta.2.

Comments

Log in Log in to join the conversation.

No comments yet. Be the first to share your thoughts.