Latest Results
feat(es/minifier): honor `/*#__PURE__*/` on property reads and destructuring patterns
`pure_getters` is a whole-program promise that no property read anywhere
has side effects, which is too blunt to enable safely. This adds a
per-site opt-in: an annotation on a single access or destructuring
pattern, so a library can mark the places it knows are safe without
turning on the unsound global option.
Pure marks normally ride on a node's `SyntaxContext`, but `MemberExpr`,
`ObjectPat` and `ArrayPat` have none. Adding one to `MemberExpr` is
feasible (the `Expr` enum has room, and `CallExpr` already sets its
size), but `ctxt` is serialized into the JS-visible AST, so it would put
a new key on every member expression in `swc.parse()` output and in the
plugin AST schema. That is a breaking change, and not one worth spending
before the optimization has proven itself.
So annotations on those nodes go in a side table keyed by source
position, collected by `info_marker` during the traversal it already
performs and read by `pure_optimizer` and `take_pat_if_unused`. It is
held by shared reference, which keeps `Parallel::create` for `Pure` a
plain copy.
Keying on `lo` rather than the whole span is deliberate: a pass may
rebuild a node with a different `hi`, but `lo` is where a leading comment
attaches. A fixture covers an annotated access that survives inlining
into its caller, which was the failure mode I was most worried about.
Annotation ownership needed care. A member expression starts at the same
position as its object, so the comment in `/*#__PURE__*/ x().y` is found
by a lookup on either node. It belongs to the call, which already
consumes it, and claiming it for the read would drop `x()` — a real
miscompile I hit and fixed before it could land. The table only claims
an annotation when the object could not have taken it.
On a pattern the annotation carries more weight than on a call: it
asserts both that the reads are pure and that the initializer is not
nullish, since dropping the pattern also removes the `TypeError` that
destructuring `null` would throw. That is documented at the use site and
pinned by a fixture.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>lukesandberg:lukesandberg/pure_annotations_on_property_access perf(es/preset-env): Reduce binary size with browserslist deflate (#12381)
**Description:**
Reduce the native binary size by upgrading `browserslist-rs` from 0.20.0
to 0.21.2 and explicitly enabling `deflate` for its bundled browser
data.
`@swc/core` `.node` release size on `aarch64-apple-darwin`:
| Configuration | Bytes | MiB |
| --- | ---: | ---: |
| browserslist-rs 0.20.0 | 26,662,128 | 25.43 |
| browserslist-rs 0.21.2 + deflate | 24,185,488 | 23.07 |
| Reduction | **2,476,640** | **2.36 (9.29%)** |
Both builds used `cargo build --release --locked -p binding_core_node`,
default features (`swc_v1`, `plugin`), the repository toolchain
(`nightly-2026-04-10`), and the unchanged release profile (fat LTO,
stripped symbols, one codegen unit, panic abort). The baseline is
`baf0ba6ee4`; both builds used the same checkout path. These are raw
native library sizes and measure the combined version upgrade and
deflate change.
Both `.node` libraries loaded through the `@swc/core` JavaScript API and
produced identical outputs for six browser-target queries, including
`supports`, regional usage, and baseline queries.
**BREAKING CHANGE:**
For Rust consumers, `BrowserData::parse_versions` now accepts
`browserslist::Distrib` from browserslist-rs 0.21 instead of 0.20, also
exposed through `swc_core::ecma::preset_env`. The changeset marks
`preset_env_base` and `swc_core` as major.
**Related issue (if exists):**
- [browserslist-rs v0.21.2 release
notes](https://github.com/browserslist/browserslist-rs/releases/tag/v0.21.2)
- [#50: Drop derivable caniuse
data](https://github.com/browserslist/browserslist-rs/pull/50)
- [#52: Compress data using
deflate](https://github.com/browserslist/browserslist-rs/pull/52)
- [#53: Deflate more
data](https://github.com/browserslist/browserslist-rs/pull/53)
- [#54: Improve deflate binary
size](https://github.com/browserslist/browserslist-rs/pull/54) Latest Branches
+3%
lukesandberg:lukesandberg/pure_annotations_on_property_access 0%
kurovskyiii:fix/sync-file-bindings-return-an-error 0%
fix/parser-asserts-linebreak © 2026 CodSpeed Technology