Pin the Codegen benchmark fixture to an immutable `benchmark-files` commit. This makes benchmark inputs reproducible and prevents `main` updates from silently changing results.
## Summary
- use the native TLS backend on macOS so HTTPS requests work with Warp and custom roots from `SSL_CERT_FILE`
- use Rustls on other targets so Linux cross-builds do not pull in `openssl-sys`
- keep the existing proxy detection and custom certificate bundle handling
## Root cause
#24178 enabled `ureq/native-tls` for all targets. On macOS this is needed for Warp because Rustls/webpki rejects part of the intercepted certificate chain with `UnsupportedSignatureAlgorithmForPublicKeyContext`.
Enabling native TLS globally also adds `native-tls -> openssl-sys` to the 32-bit and big-endian Linux dependency graphs. Those cross images do not provide target OpenSSL development files, so the builds fail before tests run.
The TLS provider and feature are now selected by target: macOS uses the platform verifier through native TLS, while all other targets continue to use Rustls.
## Summary
- load PEM root certificates from `SSL_CERT_FILE` for shared task HTTP requests
- use the native TLS verifier for custom bundles, supporting interception CAs such as Cloudflare WARP
- retain the existing Rustls/WebPKI defaults when `SSL_CERT_FILE` is unset
## Testing
- `cargo fmt --all -- --check`
- `cargo clippy -p oxc_tasks_common --all-targets -- -D warnings`
- `cargo minsize --compress-only ssl-cert-file` (downloaded all fixtures through WARP)
- `just minsize`
- `just ready` (format/check passed; workspace tests stopped on three unrelated oxlint stylish-output ANSI snapshot mismatches)
## AI disclosure
This change was developed with OpenAI Codex assistance and has been manually exercised against the reported Cloudflare WARP certificate setup.
## Summary
Self-review follow-up to #24034 (stacked on #24052), hardening the runtime suite's server transport:
- **Ephemeral ports + stdout handshake**: the fixed 32055..N port range let an orphaned server from a killed run pass the readiness probe (silently testing against a stale binary) and made two concurrent runs in different worktrees cross-talk — one run's shutdown DELETE kills the other's servers. `runtime.js` now listens on an OS-assigned ephemeral port and reports it as the first stdout line, which the runner reads as both the port and the readiness signal (the polling loop and port math are gone); remaining server stdout is drained by a background thread so `DEBUG=1` output can't deadlock a full pipe.
- **Transport retry**: monitor-oxc's first live Test262 run flipped 13 for-of cases to `timeout: global` — ureq's 10s client timeout tripping under CI load while requests queued, not a semantic change. A localhost-specific agent (no proxy, one-minute timeout) plus a single retry fixes it; the server responds even for failing tests, so a transport `Err` never carries a verdict.
Result-neutral: 17279/18277, `runtime.snap` byte-identical across repeated runs.
## Summary
Follow-up to #22590. That PR replaced the synthetic `cal.com.tsx` fixture — a concatenation of Next.js pages that declares top-level names 70–113× and emits thousands of redeclaration diagnostics, inflating semantic `sys_allocs` — with excalidraw's real, single-file `App.tsx`. But it only touched `TestFiles::complicated()` (used by `track_memory_allocations`).
This applies the same swap to every remaining benchmark that still used `cal.com.tsx`, and unifies **all** excalidraw `App.tsx` references on one pin (`f6d85bc8`):
| File | Change |
| --- | --- |
| `tasks/common/src/test_file.rs` | `minimal()` (feeds every `tasks/benchmark` criterion bench): `cal.com.tsx` → `App.tsx@f6d85bc8`. `formatter()` re-pinned `@v0.18.0` → `@f6d85bc8` |
| `napi/parser/bench.bench.js` | parser benchmark fixture → `App.tsx@f6d85bc8` |
| `napi/parser/test/parse-raw.test.ts` | bench-fixture list + size comment → `App.tsx@f6d85bc8` |
| `tasks/benchmark/benches/semantic.rs` | rewrote the now-false "`cal.com.tsx` has many errors" comment |
| `crates/oxc_ast/src/serialize/mod.rs` | removed the stale `cal.com.tsx` row from the capacity-ratio doc table |
## Why a single pin
`get_source_text` caches downloads by the last URL segment only (`App.tsx`). With two different pins live, a single `cargo bench` run would download both into the same `target/App.tsx` and silently bench whichever landed first. Re-pinning `formatter()` to `f6d85bc8` removes that collision — and the pre-existing latent one between `cargo bench` (`@v0.18.0`) and `cargo allocs` (`@f6d85bc8`).
## Notes
No committed snapshots change: these fixtures feed only timing benches and a `programRaw.toEqual(programStandard)` self-consistency test; the snapshotted `complicated()` / `minifier()` sets are untouched.
---
This PR was prepared with AI assistance; I reviewed, tested, and verified the changes.
## Summary
Adds `kitchen-sink.tsx` — a comprehensive synthetic TypeScript+JSX fixture maintained at [oxc-project/benchmark-files](https://github.com/oxc-project/benchmark-files) — to both `TestFiles::minimal()` (bench input set) and `TestFiles::complicated()` (alloc-tracking input set). The existing files in each set are untouched; this is a strict append.
## Why
The existing bench input set didn't reliably surface general-purpose perf wins above the ~1-2% measurement noise floor:
- #22580 (semantic pre-reserve) — visible because `binder.ts` exercises it
- #22594 (formatter buffer) — visible
- #22596 (minifier `try_fold_concat`) — **not visible** on the old set
- #22599 (semantic resolve-refs no-temp-Vec) — **not visible**
- #22603 (semantic var-hoist SmallVec) — **not visible**
The kitchen-sink fixes that by exercising every AST node, every transformer plugin, every minifier optimization opportunity, and every semantic step in one large file. Verified by re-benching #22596 against this fixture: **minifier mean −1.5%, min −3.7%** — above noise, signal confirmed.
## Fixture stats (cross-checked locally)
| Metric | Value |
|---|---|
| Source size | 21,117 lines / 732.90 kB |
| AST nodes | ~133,000 |
| Scopes | ~4,750 |
| Symbols | ~7,000 |
| Resolved references | ~16,000 |
| Semantic diagnostics | 0 errors / 0 warnings |
## Snap baselines
`tasks/track_memory_allocations/allocs_*.snap` updated with the kitchen-sink row across all 5 pipelines (parser / semantic / transformer / minifier / formatter). Future PRs that change allocation behavior on this fixture will produce a snap diff in CI.
## Bench-cleaner fix
`tasks/benchmark/benches/lexer.rs`'s `SourceCleaner` was missing `visit_ts_template_literal_type` — TypeScript type-level template literals (e.g. `` `${T}-${U}` `` in conditional / mapped types) are syntactically identical to value-level template literals, so the bench-mode lexer (without parser context) cannot distinguish them. Without the cleaner converting them to plain strings, kitchen-sink's type-level templates caused the lexer bench to swallow ~1 KB spans as a single `TemplateHead` and produce spurious "Unterminated string" / "Invalid Unicode escape" errors. One-line fix to mirror the existing `visit_template_literal` handling.
AI disclosure: drafted with Claude Code, reviewed manually.
## Summary
`cal.com.tsx` (1.0MB) is a concatenation of many Next.js page files. Top-level names like `getServerSideProps`, `useLocale`, `PageWrapper`, `Page`, and `getLayout` are declared 70–113 times each, so semantic emits 2,914 redeclaration `OxcDiagnostic`s. Each diagnostic allocates ~4 strings/Vecs on the system heap, accounting for the bulk of the file's 12,064 reported semantic `sys_allocs` — an artifact of the fixture rather than typical real-world TSX semantic cost.
Replace it with excalidraw [`App.tsx`](https://github.com/excalidraw/excalidraw/blob/f6d85bc80fe328e8f472636eb0d541f7bb891aa0/packages/excalidraw/components/App.tsx), pinned to master @ `f6d85bc8` (415KB, 13k lines, single source file). Semantic `sys_allocs` drops from 12,064 → 174, in line with the other fixtures.
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
| [similar](https://redirect.github.com/mitsuhiko/similar) | workspace.dependencies | major | `2.7.0` → `3.0.0` |
| [similar-asserts](https://redirect.github.com/mitsuhiko/similar-asserts) | workspace.dependencies | major | `1.7.0` → `2.0.0` |
---
### Release Notes
<details>
<summary>mitsuhiko/similar (similar)</summary>
### [`v3.0.0`](https://redirect.github.com/mitsuhiko/similar/blob/HEAD/CHANGELOG.md#300)
[Compare Source](https://redirect.github.com/mitsuhiko/similar/compare/2.7.0...3.0.0)
- Added a Git-style Histogram diff implementation exposed as
`Algorithm::Histogram`, including deadline-aware Myers fallback and
comprehensive regression/behavior tests.
- Raised MSRV to Rust 1.85 and moved the crate to Rust 2024 edition.
- Added a Hunt-style diff implementation exposed as `Algorithm::Hunt`.
- Added configurable inline refinement via `InlineChangeOptions` and
`InlineChangeMode`, including semantic cleanup and new
`TextDiff::iter_inline_changes_with_options*` methods. [#​92](https://redirect.github.com/mitsuhiko/similar/issues/92)
- Added a global disjoint-input fast path in `algorithms::diff_deadline`
to avoid pathological runtimes on large, fully distinct inputs.
- Improved `Algorithm::Myers` performance on heavily unbalanced diffs to
avoid pathological slowdowns.
- Added `diff_deadline_raw` entrypoints in the algorithm modules to bypass
shared heuristics and keep minimal intrinsic trait bounds where needed.
- Added test files in `examples/diffs` that can be used with the some of the
examples as input pairs.
- Added `CachedLookup`, a helper for adapting virtual or computed sequences by
materializing items on first access and then serving borrowed values through
normal indexing. The `owned-lookup` example demonstrates this approach for
issue [#​33](https://redirect.github.com/mitsuhiko/similar/issues/33).
- Fixed ranged indexing in the classic LCS table algorithm.
- Improved diff compaction to merge adjacent delete hunks across equal runs.
- Excluded development scripts from published crate contents. [#​87](https://redirect.github.com/mitsuhiko/similar/issues/87)
- `TextDiff::from_*` and `TextDiffConfig::diff_*` now accept owned inputs
(`String`, `Vec<u8>`, `Cow`) in addition to borrowed inputs. This allows
returning text diffs from functions without external owner lifetimes. [#​65](https://redirect.github.com/mitsuhiko/similar/issues/65)
- `TextDiff` no longer exposes `old_slices` / `new_slices`. Use
`old_len`, `new_len`, `old_slice`, `new_slice`, `iter_old_slices`,
`iter_new_slices`, `old_lookup`, and `new_lookup` instead.
- `TextDiff::iter_changes` now panics on invalid out-of-bounds `DiffOp`
ranges instead of silently truncating iteration.
- `utils::diff_lines_inline` now takes `&TextDiff` and options rather than
`(Algorithm, old, new, options)`.
- `utils::diff_lines` now avoids a second line-tokenization pass.
- Renamed `get_diff_ratio` to `diff_ratio`.
- Added first-class `no_std + alloc` support with an explicit default `std`
feature.
- Added optional `hashbrown` backend for `no_std` map storage
(`default-features = false, features = ["hashbrown"]`), while the default
`no_std` backend uses `alloc::collections::BTreeMap`.
- Made core constructors const-ready (`Capture::new`, `Replace::new`,
`NoFinishHook::new`, `InlineChangeOptions::new`, `TextDiff::configure`).
</details>
<details>
<summary>mitsuhiko/similar-asserts (similar-asserts)</summary>
### [`v2.0.0`](https://redirect.github.com/mitsuhiko/similar-asserts/blob/HEAD/CHANGELOG.md#200)
[Compare Source](https://redirect.github.com/mitsuhiko/similar-asserts/compare/1.7.0...2.0.0)
- Raised the crate edition to Rust 2024 and updated the MSRV to Rust 1.85.
- Upgraded the `similar` dependency to `3.0.0`.
- Modernized CI workflows to current GitHub Actions and added PR runs.
- Replaced atomic env-var caching with `OnceLock`.
- Minor documentation and wording fixes.
</details>
---
### Configuration
📅 **Schedule**: Branch creation - "before 10am on monday" in timezone Asia/Shanghai, Automerge - At any time (no schedule defined).
🚦 **Automerge**: Enabled.
♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box
---
This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/oxc-project/oxc).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDIuMTEiLCJ1cGRhdGVkSW5WZXIiOiI0My4xMDIuMTEiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbXX0=-->
## Summary
Improves the `print_diff_in_terminal` function with better readability and a simpler API:
**API Changes:**
- `print_diff_in_terminal(expected, result)` - Simple API that takes two strings
- `print_text_diff(diff)` - For when you already have a `TextDiff` (e.g., to use `diff.ratio()`)
**Features:**
- Show 3 lines of context above and below each change
- Add line numbers with gutter separator (`│`)
- Add blank line between adjacent hunks for visual separation
- Add `...` separator when lines are skipped between hunks
- Use single-pass streaming algorithm with small fixed-size buffer
- Colors: red (`-`) for deletions, green (`+`) for insertions, dim for context
**Formatter Example:**
- Added `--diff` flag to show diff between original and formatted code
Example output:
```
1 │class A {
2 │ #x;
3 │}
- 4 │var _x = /* @__PURE__ */ new WeakMap();
- 5 │var _B_brand = /* @__PURE__ */ new WeakSet();
4 │class B {
- 7 │ constructor() {
- 8 │ babelHelpers.classPrivateMethodInitSpec(this, _B_brand);
- 9 │ babelHelpers.classPrivateFieldInitSpec(this, _x, void 0);
+ 5 │ #x;
+ 6 │ #y() {
+ 7 │ this.#x;
8 │ }
- 11 │}
- 12 │function _y() {
- 13 │ babelHelpers.classPrivateFieldGet2(_x, this);
9 │}
```
## Test plan
- [x] `cargo check -p oxc_tasks_common` passes
- [x] Clippy passes
- [x] Verified output with `just test-transform --filter "plugins-integration/class-features-node-12/input.js"`
🤖 Generated with [Claude Code](https://claude.ai/code)
Happened to come across this. The comment didn't match the code here.
I *assume* the code is right and the comment is outdated, so this PR
amends the comment. But I don't know what this code does, so maybe it's
the other way around and the code should be changed to match the
comment?
The benchmark jobs take too long to run, change them to a minimal set.
This set of files are smaller but should provide basic coverage to real
world examples.
Replace `#[allow]` with `#[expect]` through the whole codebase.
This also surfaced many places where the `#[allow]` attributes were outdated/pointless and could be removed entirely.
Only places `#[allow]` remains are:
1. In generated code and macros, where lint errors may or may not be triggered depending on the generated code.
2. A few places where clippy malfunctions. These use e.g. `#[allow(unused, clippy::allow_attributes)]`.
In the linter, this was only used for getting a query parameter value out of a URL. These lint rules already check that the URL value is a known-good URL so we don't need to validate and parse it. I've replaced these usages with a simple helper function to get the value from the query string.
There was also a usage in the tasks directory for getting test files and I've also skipped validating here since it's not strictly necessary as we control all inputs.
Previously, #8634 visualized each spec result, but this was not enough.
If the implementation has been updated but the spec still fails, there
is no way to know if there is an improvement or not.
This time, finally, all progress is visualized! 🤩

e.g. here `arrow_function_expression` is mostly passing, except for
comment handling.
closes https://github.com/oxc-project/oxc/issues/4790
@overlookmotel enjoy ... take a look at the snapshots and probably nothing else.
The snapshots are minimal right now, but it's already showing symbols from import specifiers are not being removed. We can iterate on the snapshot representation to aid debugging later.
I'll extend this to `transformer_conformance` and `oxc-monitor` in an up coming PR.
Move `BabelOptions` to Transformer. The `output.json` is a standard babel configuration. We can reuse BabelOptions to read [babel.config.json](https://babeljs.io/docs/configuration#babelconfigjson) or our configuration(maybe oxc.config.json)
The current `from_babel_options` implementation is copied from the `transform_options` in `test_case.rs`, which I'll completely reimplement next
If submodules are outdated, it'll panic with the following message
```
Repository is outdated, please run `just submodules` to update it.
```
For us maintainers, we'll need the env `UPDATE_SNAPSHOT` to force an update.
This PR builds on #3201 to further speed up the benchmarks and reduce CI
time.
* Build and run each benchmark as separate job (like before).
* But now each bench is only built with the dependencies it needs.
* For linter benchmarks, build benchmark in 1 job (like #3201 does).
* Run each linter fixture in a separate job as they're slow.
This reduces total time to complete benchmarks from between 6m-7m to
~4m40s.
All the individual jobs complete in under 1m30s, except for building
linter benchmark which takes 2m30s. So there won't be the problem of
blocking the CI queue that there was before.
NB: I did try this before, and didn't see a benefit. But I realized
today what I was doing wrong - it only works once the caches are
populated by a previous run on main branch.
So the CI times in this PR won't look good, but once it's merged to
main, it will take effect. Here it is running on main branch of my fork:
https://github.com/overlookmotel/oxc/actions/runs/9030511348
I also added a step to delete the temp artefacts which aren't needed
once the run has completed.
Follow-on from #2751. Further shards linter benchmarks so each fixture runs in its own job.
This reduces total time to run benchmarks by another ~75 secs. So approx 2.5 mins shaved off in total.
Following #2297, this adds another benchmark.
This one is from radix-ui website. I've chosen this particular file
because it differs from the other benchmark sources in 3 ways:
1. JSX not TSX (despite the file extension).
2. Contains no logic, only JSX component hierarchy, and content text.
3. Very small (60 LOC).
The last is particularly important, I think. Often developers will be
working on small files (single component per file convention). And some
possible directions for the parser (SIMD etc) involve optimizing chewing
through chunks of text, with a de-opt at the end to process the final
batch of bytes. If that imposes a penalty on short files, this benchmark
will surface it.
---------
Co-authored-by: Boshen <boshenc@gmail.com>