La release Oxc crates_v0.137.0, publiée le 18 juin 2026, livre deux nouvelles passes de treeshaking pour le minifier, un rafraîchissement de portée incrémental de longue haleine, une erreur d'analyseur conviviale pour les éléments JSX adjacents, et un correctif du React Compiler pour les imports référencés uniquement par une clé calculée. La release comporte aussi deux changements cassants de l'API de configuration ESTree et la liste de patches de perf la plus dense du projet à ce jour : onze entrées de performance réparties entre l'analyseur, le minifier, le mangler, le transformer et le React Compiler.
C'est la première release de crates depuis v0.135 le 8 juin et la deuxième depuis que l'intégration native du React Compiler dans Bun a été mergée dans oven-sh/bun le 20 juin. Le port de Bun tire l'espace de travail Rust amont de facebook/react directement, donc les changements d'Oxc ici remontent toujours vers le compilateur amont via le port de Meta et l'adaptateur react_compiler_oxc que les autres bundlers reprennent.
Le titre : deux nouvelles passes de treeshaking pour le minifier
La nouvelle passe que les utilisateurs sentiront en premier est treeshake pure typed arrays and Set/Map array literals (#23469, Dunqing). Le minifier d'avant v0.137 savait déjà treeshaker un const x = [1, 2, 3] dont le contenu était pur, mais il s'arrêtait à la frontière des tableaux typés : un new Uint8Array([1, 2, 3]) dont les octets étaient inutilisés restait dans la sortie, tout comme un new Map([["a", 1], ["b", 2]]) dont les entrées n'étaient jamais lues. La passe de v0.137 reconnaît ces constructeurs, parcourt le littéral de tableau interne, et le traite de la même façon que la passe de littéraux de tableau classique : pur + inutilisé => on supprime.
Le complément est inline const value for read-only vars (#22593, également Dunqing). Le minifier d'avant v0.137 n'inlinait un binding const que si le binding était utilisé exactement une fois ; v0.137 inline la valeur sur chaque site d'utilisation quand le binding est un const et que la valeur est traitée comme read-only par l'analyse type-aware. Cela donne au reste du minifier (constant folding, conditionnels, simplification de return statements) une chance de plier le résultat. La description de la PR parcourt un exemple travaillé : un const FOO = computeFoo() suivi plus loin d'un if (FOO > 0) se replie en la comparaison inlinée quand computeFoo est une arrow pure qui retourne un littéral, et en une branche à condition constante quand c'est une arrow pure qui retourne une constante.
Les deux passes sont gardées par des flags de CompressOptions, désactivées par défaut dans v0.137. Les notes de release sont explicites : le CompressOptions par défaut dans oxc_minifier v0.137 correspond à v0.136, donc les gains sont opt-in.
Le plus gros changement de perf : rafraîchissement de portée incrémental
Le plus gros changement de perf de v0.137 est Incremental scoping refresh, delete LiveUsageCollector (#23197, Dunqing). LiveUsageCollector était la seule structure d'oxc_minifier qui parcourait l'arbre de portée complet à chaque passe du minifier pour déterminer quels symboles étaient encore en usage. Le rafraîchissement de portée incrémental découpe cela en mises à jour par statement et saute le parcours complet quand aucun changement en aval n'invalide le cache.
La description de la PR de Dunqing est directe : LiveUsageCollector était le plus gros coût constant dans les grosses exécutions de minifier, et la seule passe d'oxc_minifier qui s'exécutait encore en O(scope) à chaque entrée de corps de fonction. Sa suppression élimine le seul interne du minifier qui avait besoin de l'arbre de portée complet à chaque entrée, et le reste du minifier peut maintenant utiliser un rafraîchissement par statement moins coûteux. Les notes de release ne donnent pas de chiffre, mais les correctifs de perf liés de la même release racontent la même histoire :
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)
Le correctif semantic/mangler/minifier de #23352 est celui sur lequel les autres entrées de perf s'appuient : Semantic::stats renvoyait auparavant des comptages de nœuds qui ne correspondaient pas à ce que le mangler allait calculer, donc le mangler devait refaire le travail. Le correctif fait correspondre les comptages, et le reste de la release peut les réutiliser. v0.137 est la première release où la pipeline semantic/mangler/minifier est cohérente sur les stats.
Deux changements cassants de la config ESTree
Les deux changements cassants sont tous les deux dans la couche optionnelle de compatibilité ESTree, pas dans le compilateur lui-même. Make whether to include TS fields a runtime option (#23574, overlookmotel) déplace la décision d'exposer ou non les champs spécifiques à TypeScript dans l'AST ESTree (annotations TS, paramètres de type, nœuds spécifiques à TS) d'une feature de build Cargo vers une option runtime sur le builder ESTree. ESTree config use methods not consts (#23573, overlookmotel) remplace les const publics de la struct de config ESTree par des méthodes, donc les sites d'appel passent de config.include_ts_fields à config.include_ts_fields().
Les crates en aval qui construisent un AST ESTree personnalisé doivent mettre à jour leurs appels de config. Le compilateur lui-même, l'analyseur, le transformer, le minifier et le React Compiler sont tous inchangés par le remaniement ESTree. La couche ESTree est celle qui permet à Oxc d'émettre un AST qui correspond à la spec ESTree, ce que consomment des outils comme Rollup, esbuild et la chaîne de loaders acorn de webpack.
Les entrées React Compiler
Les deux entrées React Compiler sont les plus pertinentes par rapport à l'actualité de la veille. Keep imports referenced only by a computed key (#23586, Boshen) corrige un vrai trou de correction dans le suivi d'imports du React Compiler : un import dont la seule utilisation est le côté droit d'une clé calculée (par exemple, obj[SomeImport] où SomeImport est un import default renommé) était supprimé, ce qui se compilait en un comportement indéfini dans la HIR du React Compiler. Le correctif maintient l'import en vie dès qu'une clé calculée y résout.
Borrow binding names in prefilter instead of allocating (#23471, Yunfei He) est une entrée de perf, pas un correctif. Le prefilter est la première passe du React Compiler sur un corps de fonction pour décider si le corps est un candidat à la compilation ; le prefilter allouait auparavant une String par hit, ce qui sur une grosse base de code React avec beaucoup de composants s'additionne. Le borrow supprime l'allocation.
Ces changements vont dans l'espace de travail Rust amont de facebook/react, pas seulement dans la fork Oxc. L'intégration native du React Compiler dans Bun porte l'espace de travail compiler/crates/ amont directement, donc les entrées React Compiler de v0.137 seront dans la prochaine synchronisation de Bun. Oxlint et oxfmt tirent les dernières crates selon leur cadence hebdomadaire de release, et la release oxlint 1.70 il y a deux semaines était la première à livrer le port amont du React Compiler comme crate Rust ; v0.137 est la deuxième release de crates à porter du travail de perf et de correction sur le React Compiler.
Le travail UX de l'analyseur
Deux changements d'analyseur visent l'ergonomie du développeur plutôt que la perf brute. Parser: add friendly error for adjacent JSX elements (#23378, sapphi-red) remplace l'erreur cryptique « unexpected token » que l'analyseur émettait auparavant quand deux éléments JSX adjacents (par exemple <a /><b /> au début d'un fichier sans wrapper de fragment explicite) échouaient à parser, par un message qui nomme le problème et pointe sur le token fautif. Parser: treat a line comment after ':' as leading, not trailing (#23515, Dunqing) corrige un bug d'attribution de commentaires de longue date où un commentaire // foo après un : était attaché au token précédent au lieu du suivant, ce qui rendait les source maps fausses dans certains cas.
Deux correctifs de correction du minifier à signaler
Les deux correctifs du minifier sont petits mais du genre qui mord en production :
Minifier: keep Object introspection calls on a possible Proxy(#23483, Dunqing) empêche le minifier de supprimerObject.keys(obj),Object.values(obj),Object.entries(obj)etObject.getOwnPropertyDescriptor(obj, key)quandobjpourrait être unProxy, parce que l'appel peut invoquer le trapownKeysougetOwnPropertyDescriptordu proxy et renvoyer des valeurs arbitraires.Minifier: keep new Map/WeakSet/WeakMap with a string argument(#23470, Dunqing) empêche le minifier de supprimer unnew Map([["a", 1]])dont l'argument littéral est un tableau à clés string d'entrées pures, parce que l'ordre d'itération du constructeur compte et que le minifier le traitait comme un no-op.
Les deux appartiennent à la même famille que la nouvelle passe treeshake pure typed arrays, mais en sens inverse : la nouvelle passe est une extension opt-in de ce que le minifier peut prouver comme sûr à supprimer, et les deux correctifs sont des corrections d'endroits où le minifier d'avant v0.137 était trop agressif.
Ce que v0.137 ne change pas
La release ne change ni les défauts de l'analyseur ou du minifier, ni la surface du transformer, ni l'API publique du React Compiler. Les changements cassants sont confinés à la couche optionnelle de config ESTree. Les API des crates oxc_ast, oxc_parser, oxc_semantic, oxc_transformer, oxc_minifier, oxc_mangler et oxc_react_compiler sont toutes rétrocompatibles avec v0.136. La prochaine release des apps oxlint et oxfmt sur la cadence hebdomadaire du lundi reprendra les gains de perf de v0.137 dans les crates parser, minifier et React Compiler, plus la suppression de LiveUsageCollector dans oxc_minifier.
La release est aussi la deuxième à porter la nouvelle convention de l'équipe Oxc de découper le corps en sections à en-tête emoji (💥 BREAKING CHANGES, 🚀 Features, 🐛 Bug Fixes, ⚡ Performance, 📚 Documentation), qu'Oxc v0.135 a introduite. Le pattern correspond au format de changelog de Biome et aux notes de release de Vite 8, et facilite le scan d'une release pour trouver ce qui compte pour votre code d'un coup d'œil.



