---
title: "SWC v1.15.43 Lands the React Compiler as a First-Class Transform, Fixes a Silent Template Literal Minifier Bug, and Aligns `unsafe_math` with Terser"
description: "SWC v1.15.43, published on 2026-06-22 with swc_core v71.0.3, ships the experimental Rust React Compiler as a configurable SWC transform via .swcrc jsc.transform.reactCompiler (PR #11917, 54 files, 12,986 additions); fixes a silent template literal minifier bug where `compress` dropped text after the left template's last interpolation when concatenating two template literals (#11939); gates Number(x) -> +x on both `unsafe: true` AND `unsafe_math: true` to match terser v4.3.11+ (#11944, #11949); corrects scope for ES2022 private property brand checks (#11953); and lands seven internal React Compiler fixes (#11940, #11943, #11946, #11950, #11951, #11952, #11957) plus a parser fix that allows no-default builds (#11956) and a docs entry on the untrusted input security scope (#11937)."
date: 2026-06-23
image: "/images/heroes/2026-06-23--swc-v1-15-43-react-compiler-template-literal-bug.png"
author: lschvn
tags: ["tooling", "performance"]
tldr:
  - "SWC v1.15.43, published 2026-06-22, ships the Rust React Compiler as a first-class configurable transform via the `.swcrc` `jsc.transform.reactCompiler` field (PR #11917, 54 files, 12,986 additions). The transform is gated behind a feature flag in `swc_core` v71.0.3 and currently depends on git references to the upstream `facebook/react` Rust workspace; the integration is the third React Compiler integration story in the tooling press after [Bun's bundler integration](/articles/2026-06-21--bun-react-compiler-bundler-integration-20x) (2026-06-20) and the [Oxc v0.137 React Compiler hooks](/articles/2026-06-22--oxc-v0-137-react-compiler-treeshake-perf) (2026-06-18)."
  - "The release fixes a silent template literal minifier bug (#11939) where the `compress` pass concatenated two template literals and updated the merged quasi's `raw` but not its `cooked`, dropping the text that followed the left template's last interpolation. The bug affected every rspack and rsbuild user that ran `compress: true` on template-literal concatenation: `` `<b>${1}</b>` + `<i>${2}</i>` `` minified to `\"<b>1<i>2</i>\"` instead of `\"<b>1</b><i>2</i>\"`, silently. The fix lands in `concat_tpl` and now mirrors `raw` merging to `cooked`."
  - "The release also gates `Number(x)` to `+x` on BOTH `unsafe: true` AND `unsafe_math: true` (#11944, #11949), aligning with terser since v4.3.11. The pre-v1.15.43 SWC minifier performed the rewrite with `unsafe: false` and `unsafe_math: true`, which broke parity with terser and caused bundle output to differ between SWC and terser on the same source. The fix is a behavior change for users who relied on the SWC behavior; the docs update and the docs entry on untrusted input security scope (#11937) make the new boundary explicit."
faq:
  - question: "What is the headline feature in SWC v1.15.43?"
    answer: "The headline is the experimental Rust React Compiler landing as a first-class SWC transform (#11917, 54 files, 12,986 additions). The integration adds the `swc_ecma_react_compiler` bridge crate, SWC <-> React Compiler AST and scope conversion, `.swcrc` `jsc.transform.reactCompiler` configuration, diagnostics forwarding, and JS / WASM option types. It is gated behind a feature flag in `swc_core` v71.0.3 and currently depends on git references to the upstream `facebook/react` Rust workspace that [facebook/react#36173](https://github.com/facebook/react/pull/36173) (merged 2026-06-09) shipped. The first published Rust crates are not yet available; until they are, the integration is experimental and not yet ready for production use."
  - question: "Why is the template literal minifier bug worth calling out?"
    answer: "The bug is `fix(es/minifier): Preserve cooked when concatenating template literals` (#11939), and it is the worst kind of minifier bug: silent, content-dropping, and not a syntax error. When `compress` folded `a + b` and both sides were template literals, `concat_tpl` merged the boundary quasis by updating `raw` but not `cooked`. Downstream passes (`eval_tpl_as_str`, `eval_nested_tpl`, `compress_tpl`) read `cooked` to evaluate the template to a string, so the text after the left template's last interpolation was dropped. Example: `` `<b>${1}</b>` + `<i>${2}</i>` `` minified to `\"<b>1<i>2</i>\"` instead of `\"<b>1</b><i>2</i>\"`. The bug affected every rspack and rsbuild user that ran `compress: true` on template-literal concatenation; the regression test in the PR runs the original and the minified code and compares the output."
  - question: "How does the unsafe_math fix change bundle output?"
    answer: "The fix is `fix(es/minifier): Gate Number(x) -> +x on unsafe flag` (#11944, follow-up #11949). Before v1.15.43, the SWC minifier rewrote `Number(x)` to `+x` whenever `unsafe_math: true` was set, even with `unsafe: false`. Terser since v4.3.11 has required BOTH `unsafe: true` AND `unsafe_math: true` for the rewrite. The v1.15.43 fix brings SWC into parity: `Number(x)` to `+x` only fires when both flags are on. The change is behavior-breaking for users who relied on the SWC behavior with `unsafe: false`; the bundle output for that config is now `Number(x)` instead of `+x`. The expected minified output is the original `Number(x)`."
  - question: "What does the React Compiler integration mean for rspack and rsbuild users?"
    answer: "rspack and rsbuild already wrap SWC's JS transformer, so the React Compiler transform is available to them once they enable the `react_compiler` feature in their SWC build and set `jsc.transform.reactCompiler` in their `.swcrc`. The integration is currently gated behind the `swc_core` `react_compiler` feature flag, and the `swc_ecma_react_compiler` bridge is not yet in the published crates.io index. The PR description is explicit: 'Wait for the React Compiler Rust crates to be published, then replace the temporary git dependencies with published crate versions.' Until that lands, downstream consumers should expect a git-source build of `swc_core` if they want to experiment."
  - question: "What other React Compiler fixes ship in this release?"
    answer: "Seven internal React Compiler fixes: `fix(es/react-compiler): Skip TypeScript this pseudo-params in scope collector` (#11940, mofeiZ) skips the synthetic TypeScript `this` parameters that tsserver adds to methods so the scope collector does not treat them as real bindings; `fix(es/react-compiler): Scope ClassStaticBlock and TsModuleBlock as var boundaries` (#11943, mofeiZ) treats the two block-like TS / ES constructs as scope boundaries so declarations inside them do not leak into the enclosing scope; `fix(react-compiler): Avoid reporting non-fatal success errors as diagnostics` (#11951, mofeiZ) stops the compiler from reporting expected success markers as user-visible errors; `fix(react-compiler): React compiler AST conversion for wrapped assignment targets` (#11952, mofeiZ) fixes a real correctness gap where assignments to wrapped expressions (e.g. `(a.b).c = 1`) failed to convert; `fix(react-compiler): Disable parser default features` (#11957, mofeiZ) tightens the parser feature set so the bridge does not pull in parser features that conflict with the React Compiler's scope model; `chore(es/react-compiler): Update forked react compiler to 0.2.0` (#11946) updates the internal forked React Compiler to 0.2.0; and `refactor(es/react-compiler): Preserve TS metadata during AST roundtrip` (#11950, mofeiZ) keeps the TypeScript-specific metadata on the AST when the bridge round-trips from SWC's AST to the React Compiler's HIR and back."
  - question: "What is the ES2022 brand check scope fix?"
    answer: "`fix(es/es2022): Correct scope for private property brand checks` (#11953) tightens the scope tracking for the ES2022 private-field brand check, the `#field in obj` syntax that decides whether a private field is accessible from a given call site. The pre-v1.15.43 implementation tracked brand checks at the wrong scope level, which caused some private-field accesses to be reported as errors when they were not, and some to be allowed when they were not. The fix scopes the brand check to the class the field is declared on, matching the spec."
  - question: "Are there any breaking changes in SWC v1.15.43?"
    answer: "Two behavior changes that users should know about. First, `Number(x)` to `+x` now requires `unsafe: true` AND `unsafe_math: true` (#11944), matching terser; the previous SWC behavior was gated on `unsafe_math: true` alone, which was out of step with terser since v4.3.11. Second, the parser no-default builds fix (#11956, dongzhi) removes default features from the parser when the React Compiler integration is enabled, which means parser features outside the React Compiler's scope need to be opted into explicitly. Neither change ships as a Cargo crate API break, but both can change bundle output."
  - question: "What is the docs entry on untrusted input security scope?"
    answer: "`docs: Document untrusted input security scope` (#11937) is a documentation-only PR that adds an explicit section to the SWC README clarifying what is and is not safe to feed to SWC's `parse` and `process_print` entrypoints. The new section makes it explicit that SWC's parsing and transformation surface is not hardened against adversarial input: a malformed source file can still trigger a panic or an out-of-bounds allocation in downstream transforms. The docs entry is a useful tripwire for users who ingest untrusted code; the recommendation is to run SWC inside a sandboxed subprocess when the source cannot be trusted."
---

[SWC v1.15.43](https://github.com/swc-project/swc/releases/tag/v1.15.43), published on 2026-06-22 with `swc_core` v71.0.3, is the first SWC release that ships the Rust React Compiler as a configurable transform, fixes a silent template literal minifier bug that affected every rspack and rsbuild user, and aligns the `unsafe_math` minifier flag with terser v4.3.11+. The release is the seventeenth `1.15.x` patch in the [SWC `1.15` cycle](https://github.com/swc-project/swc/releases) that has run since early 2026 and the first to land on top of `swc_core` v71.

The headline work is in three places: the `swc_ecma_react_compiler` bridge that lands the React Compiler as a first-class SWC transform, the template literal `concat_tpl` fix that closes the silent minifier bug, and the `unsafe_math` behavior change that brings SWC into parity with terser. Seven internal React Compiler fixes, an ES2022 brand-check scope fix, a parser no-default builds fix, a docs entry on untrusted input security, and the production tracing hooks removal round out the release.

## The template literal minifier bug

The most user-impactful change in v1.15.43 is `fix(es/minifier): Preserve cooked when concatenating template literals` ([#11939](https://github.com/swc-project/swc/pull/11939), kdy1). The pre-v1.15.43 `concat_tpl` pass folded `a + b` when both sides were template literals by merging the boundary quasis: the last quasi of the left template was concatenated with the first quasi of the right template, and the merged quasi was emitted with `raw` set to the concatenation of the two `raw` strings. The `cooked` slot was not touched.

That asymmetry was the bug. Downstream passes (`eval_tpl_as_str`, `eval_nested_tpl`, `compress_tpl`) evaluate the template to a string via `cooked`, so the text after the left template's last interpolation was silently dropped. The result was wrong but not a syntax error, so it shipped.

The reproducer in the PR description is `` `<b>${1}</b>` + `<i>${2}</i>` ``. Pre-v1.15.43, the minifier emitted `<b>1<i>2</i>` (note: the closing `</b>` is gone). The expected output is `<b>1</b><i>2</i>`. The same pattern affects any concatenation of two template literals that both contain at least one interpolation: `` `${1}px` + `${2}px` `` minified to `${1}${2}px` with the wrong delimiter. The bug only fired when `compress: true` was set, which is the default in rspack's `optimization.minimize` and rsbuild's `output.overrideBrowserslist` minify path.

The fix updates `cooked` in the `Tpl + Tpl` branch of `concat_tpl` the same way `raw` is updated, falling back to `None` if either side's `cooked` is `None` (which signals an invalid escape sequence). The sibling branches `Tpl + Str` and `Str + Tpl` already merged `cooked` correctly; only the `Tpl + Tpl` branch was missing it. The PR adds an exec regression test that runs the original and the minified code and compares the output, plus 49 lib tests and 481 exec tests in the affected `swc_ecma_minifier` crate.

The PR description notes that the bug also surfaces through every bundler that wraps SWC's JS minifier, including rspack and rsbuild. Users who want to verify the fix on a known-bad input can run the smallest reproducer from the PR:

```js
require("@swc/core").minifySync("x = `a${0}]` + `${0}b`", { compress: true }).code
// pre-v1.15.43:  x="a00b";
// post-v1.15.43: x="a0]0b";
```

## The React Compiler as a first-class SWC transform

The headline feature is `feat(es/react-compiler): Add React Compiler` ([#11917](https://github.com/swc-project/swc/pull/11917), kdy1), the 12,986-addition, 54-file PR that lands the Rust React Compiler as a configurable SWC transform. The integration adds the `swc_ecma_react_compiler` bridge crate, the SWC <-> React Compiler AST and scope conversion layer, the `.swcrc` `jsc.transform.reactCompiler` configuration field, diagnostics forwarding from the React Compiler's HIR to SWC's `Handler`, and JS / WASM option types. The transform is gated behind the `react_compiler` feature flag in `swc_core` v71.0.3 and is currently experimental.

The Rust React Compiler itself is the work in [facebook/react#36173](https://github.com/facebook/react/pull/36173) (merged 2026-06-09, by [Mofei Z](https://github.com/mofeiZ) and the React Compiler team), which ported the original TypeScript React Compiler to Rust as a Babel-AST-in / Babel-AST-out library with three example integrations (Babel, Oxc, SWC). The architecture uses a Babel-style AST as the public API and converts to and from the native representation of each integration; SWC's bridge converts between SWC's ESTree-flavored AST and the React Compiler's Rust Babel AST.

The PR description is explicit about the not-yet-published crates dependency:

> Wait for the React Compiler Rust crates to be published, then replace the temporary git dependencies with published crate versions.

Until that lands, the integration uses git references to the upstream `facebook/react` Rust workspace, which means downstream consumers (rspack, rsbuild, custom SWC users) need to build `swc_core` from a git source if they want to experiment. The PR title is `Add React Compiler` and the entry in the CHANGELOG is `feat(es/react-compiler): Add React Compiler`; the feature is the third React Compiler integration story in the tooling press, after [Bun's bundler integration on 2026-06-20](/articles/2026-06-21--bun-react-compiler-bundler-integration-20x) (PR bun#32504) and the [Oxc v0.137 React Compiler treeshake hooks on 2026-06-18](/articles/2026-06-22--oxc-v0-137-react-compiler-treeshake-perf) (PR oxc#23471, oxc#23586).

The user-facing config field is `jsc.transform.reactCompiler` in `.swcrc`. The shape is documented in the PR but not yet in the published `swc` crate docs; the experimental flag is the way to opt in.

## The unsafe_math behavior change

The third headline change is `fix(es/minifier): Gate Number(x) -> +x on unsafe flag` ([#11944](https://github.com/swc-project/swc/pull/11944), with the follow-up in [#11949](https://github.com/swc-project/swc/pull/11949)). The pre-v1.15.43 SWC minifier rewrote `Number(x)` to `+x` whenever `unsafe_math: true` was set, even with `unsafe: false`. Terser since v4.3.11 has required BOTH `unsafe: true` AND `unsafe_math: true` for the same rewrite.

The asymmetry is documented in [#11944](https://github.com/swc-project/swc/issues/11944): a TypeScript source `export function foo(x) { return Number(x) }` with `unsafe: false, unsafe_math: true` minifies in SWC to `+x` and in terser to `Number(x)`. The two outputs differ on every bundle that uses the unsafe-math-only config, which is the documented Terser option for "safe-enough" minification of mathematical expressions.

The v1.15.43 fix gates the rewrite on both flags, matching terser. The change is behavior-breaking for users who relied on the SWC behavior: with `unsafe: false, unsafe_math: true`, the minifier now preserves `Number(x)`. The fix is documented in the CHANGELOG and the docs entry on untrusted input security scope ([#11937](https://github.com/swc-project/swc/pull/11937)) adds a section to the README that clarifies the security boundary for SWC's parser and process_print entrypoints.

## The React Compiler internal fixes

Seven internal React Compiler fixes land alongside the bridge integration. The fixes are smaller than the bridge itself but they are the work that makes the bridge usable for real codebases.

- `fix(es/react-compiler): Skip TypeScript this pseudo-params in scope collector` ([#11940](https://github.com/swc-project/swc/pull/11940), mofeiZ) tells the scope collector to ignore the synthetic `this` parameters that tsserver adds to TypeScript methods.
- `fix(es/react-compiler): Scope ClassStaticBlock and TsModuleBlock as var boundaries` ([#11943](https://github.com/swc-project/swc/pull/11943), mofeiZ) treats `ClassStaticBlock` (the `static { ... }` block in ES2022 class bodies) and `TsModuleBlock` (the body of `namespace foo { ... }` and `module foo { ... }`) as scope boundaries, so declarations inside them do not leak into the enclosing scope.
- `fix(react-compiler): Avoid reporting non-fatal success errors as diagnostics` ([#11951](https://github.com/swc-project/swc/pull/11951), mofeiZ) stops the React Compiler from reporting its own success markers as user-visible errors, which was producing noisy `cargo test` output.
- `fix(react-compiler): React compiler AST conversion for wrapped assignment targets` ([#11952](https://github.com/swc-project/swc/pull/11952), mofeiZ) handles assignments to wrapped expressions like `(a.b).c = 1`, which the bridge previously failed to convert.
- `fix(react-compiler): Disable parser default features` ([#11957](https://github.com/swc-project/swc/pull/11957), mofeiZ) tightens the parser feature set so the bridge does not pull in parser features that conflict with the React Compiler's scope model.
- `chore(es/react-compiler): Update forked react compiler to 0.2.0` ([#11946](https://github.com/swc-project/swc/pull/11946)) updates the internal forked React Compiler to 0.2.0, which brings the bridge in line with the upstream Rust compiler.
- `refactor(es/react-compiler): Preserve TS metadata during AST roundtrip` ([#11950](https://github.com/swc-project/swc/pull/11950), mofeiZ) keeps the TypeScript-specific metadata on the AST when the bridge round-trips from SWC's ESTree-flavored AST to the React Compiler's HIR and back.

The feature flag for the re-export of the React Compiler transform is `feat(swc): Gate react compiler re-export` ([#11941](https://github.com/swc-project/swc/pull/11941)), which means the `swc` crate's `react_compiler` module is behind the same `react_compiler` feature flag as the bridge crate. Downstream users who want the JS / WASM bindings need to enable both.

## The ES2022 brand check scope fix

`fix(es/es2022): Correct scope for private property brand checks` ([#11953](https://github.com/swc-project/swc/pull/11953)) tightens the scope tracking for the ES2022 private-field brand check. The `#field in obj` syntax is the runtime check that decides whether a private field is accessible from a given call site; the pre-v1.15.43 implementation tracked brand checks at the wrong scope level, which caused some private-field accesses to be reported as errors when they were not, and some to be allowed when they were not. The fix scopes the brand check to the class the field is declared on, matching the spec.

The fix is the third ES2022 correctness fix in the SWC 1.15 cycle, after the private-method `super` rewrite fix in v1.15.39 and the static initialization block scope fix in v1.15.41. ES2022 private fields are still a work in progress in tooling; the fix does not change the parser surface, only the transform pass.

## What v1.15.43 does not change

The release does not change the parser surface, the React Compiler's public API beyond the new transform, or the public `swc_ecma_*` crate APIs. The minifier's `CompressOptions` defaults match v1.15.41; the new `unsafe_math` behavior is gated on the existing `unsafe` flag. The `swc_core` v71.0.3 bump is the work that lands the `react_compiler` feature flag in the published `swc_core` crates; the v71 line is the first to carry it.

The release also removes the production tracing hooks (`refactor: Remove production tracing hooks`, [#11945](https://github.com/swc-project/swc/pull/11945), kdy1). The pre-v1.15.43 SWC binary shipped with tracing hooks that could be enabled via the `SWC_TRACE` environment variable for production debugging; the hooks added a small but measurable cost on every parse / transform call. The v1.15.43 release removes the hooks entirely, with the trade-off that production tracing is no longer available without a debug build.

## What to watch

Three follow-ups are likely in the next two to six weeks. The first is the publication of the React Compiler Rust crates on crates.io, which unblocks the integration from the temporary git dependency to a published version and lets rspack and rsbuild ship the transform in their next stable releases. The second is the next `swc_core` minor release (v71.0.4 or v71.1.0), which is likely to ship more of the React Compiler's HIR passes exposed as SWC transforms. The third is the next Oxc crates release, which is scheduled for Monday 2026-06-29 and is the first crates release not in the v0.137 cycle; it is likely to carry more React Compiler hooks that complement the SWC bridge.