## What
Adds an opt-in `reactCompiler.reportDiagnostics` option to
`oxc-transform-react`. When `true`, the recoverable diagnostics the
React Compiler produced for a successful compile
(`CompileResult::Success { diagnostics }`) are appended to
`result.errors` alongside code, keeping the category severity the
compiler assigned (`Error` for `Suppression`, `Warning` for
`IncompatibleLibrary`, ...). `fatal` keeps its meaning and tells whether
`code` is usable.
The default is unchanged: recoverable diagnostics stay omitted, matching
Babel's default `logger: null` as decided in #26128.
## Why
Since #26128 (0.148.0) there is no way to learn *why* a function was
skipped: `errors` is fatal-only, and `panicThreshold` is not a
substitute because it aborts at the first diagnostic without producing
code. Consumers that need the reasons — a burndown inventory when
adopting the compiler, or checking which `eslint-disable` suppressions
actually took effect — lost their only channel. Details and a repro are
in #26318.
Two concrete downstream effects on 0.148+:
- `@vitejs/plugin-react` added `logDiagnostics`
(vitejs/vite-plugin-react#1431) one day after #26128, reading
recoverable diagnostics from `result.errors`; with the current binding
that option is a no-op. With this PR it only needs to forward
`reportDiagnostics: logDiagnostics`.
- `outputMode: 'lint'` / `noEmit` return `errors: []`, so lint mode has
no observable output at the Node boundary.
Babel's `logger` is the knob that turns these reports on; this option is
the non-callback equivalent. Upstream's own native bridge
(`babel-plugin-react-compiler-rust`) likewise returns every event on the
native result and lets the JS shim apply `logger: null`.
## Design notes
- **Opt-in rather than a new always-populated field**, so the default
result is byte-identical to today and nobody pays for rendering
codeframes they never read.
- **Reuses `errors`** instead of adding a second array: `errors` already
carries non-fatal parser and transformer warnings, and the 0.147 shape
(recoverable compiler diagnostics in `errors`, `fatal` to tell if output
is usable) is what existing consumers were written against.
- The severities are forwarded as the compiler assigned them (no `Error
→ Warning` rewrite as in 0.147); `fatal` is the fatality signal, as
documented on `oxc_react_compiler::compile`.
## Verification
- `napi/transform-react`: `pnpm run build-dev && pnpm test` — 33 tests
pass (3 new: opt-in vs default, multiple diagnostics with their own
severities, lint mode).
- `cargo fmt --check`, `cargo clippy -p oxc_transform_react_napi
--all-targets --all-features -- -D warnings`, `typos` on the touched
files.
- Repro from #26318 against this build (`memoized` = `_c(` count, shows
the suppression is still honored):
```
default reportDiagnostics: true
default errors: 0 errors: 1 (Suppression, label = the eslint comment)
no suppressions errors: 0 errors: 0, memoized: 2
lint errors: 0 errors: 1, memoized: 0
panic fatal, 1 unchanged
```
- Ran the real consumer from #26318 (a suppression gate that maps
`react-compiler(Suppression)` labels back to the component they cover)
against this build: with the option it recovers all 5 expected sites
across the codebase; against published 0.149.0 it finds none.
`index.d.ts` is regenerated by `napi build`;
`transform-react.wasi.d.cts` mirrors it by hand, as in #26128.
closes#26318
---
AI usage disclosure (per AGENTS.md): this PR was drafted with Claude
Fable 5.1. I reviewed the diff; the verification steps above were run on
my machine against this branch.
---------
Co-authored-by: JacktheRanger <219502738+JacktheRanger@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Cameron Clark <cameron.clark@hey.com>
## Summary
- skip React Compiler transform and lint analysis for `node_modules` by default
- let explicit transform `sources` allowlists opt dependencies back in
- document the behavior and add regression coverage
## Validation
- focused Oxlint and transform-react checks
- Clippy with warnings denied
- `just ready` reached the all-features suite; three Oxlint ANSI-color snapshots differed in this environment
AI assistance: Codex was used to implement and verify this change.
Standardize React Compiler diagnostics with concise titles, primary labels, actionable help, notes, structured categories, and official guidance links.
Preserve React guidance when diagnostics are surfaced through Oxlint, and refresh affected snapshots.
AI-assisted; reviewed and validated by the contributor.
Centralizes React compiler diagnostics in explicit `#[cold]` functions and removes the `[ReactCompiler]` prefix, keeping diagnostic formatting off hot paths. Updates related NAPI expectations.
AI assistance was used.
Anchor React Compiler-generated imports before the first source statement so downstream JSX transforms continue to read leading `@jsxImportSource` pragmas.
Validated with `just ready` and the transform-react binding suite. AI-assisted; the author remains responsible for review.
Disable exhaustive memo dependency validation by default and align
suppression handling.
AI-assisted.
<sub>Stack created with <a
href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a
href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
Fix React Refresh when used with the React Compiler N-API transform by
preserving original hook argument and binding-pattern spans through
compiler codegen.
This prevents refresh signature generation from panicking and keeps
signatures based on the original source.
Validated with `just ready` and the React transform N-API suite.
Generated with AI assistance; reviewed and validated by the contributor.
Restructure `oxc-transform-react` options around `reactCompiler` and the shared JSX/Fast Refresh configuration.
Generated with AI assistance; reviewed and validated by the contributor.