Skip to content

feat(es/react-compiler): Add React Compiler#11917

Merged
kdy1 merged 4 commits into
mainfrom
feat/react-compiler
Jun 15, 2026
Merged

feat(es/react-compiler): Add React Compiler#11917
kdy1 merged 4 commits into
mainfrom
feat/react-compiler

Conversation

@magic-akari

@magic-akari magic-akari commented Jun 4, 2026

Copy link
Copy Markdown
Member

Description:

Add experimental SWC support for the Rust React Compiler from react/react#36173.

This adds the swc_ecma_react_compiler bridge, SWC <-> React Compiler AST/scope conversion, .swcrc jsc.transform.reactCompiler configuration, diagnostics forwarding, JS/WASM option types, and tests ported from the upstream SWC integration.

TODO:

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

BREAKING CHANGE:

Related issue (if exists):

@changeset-bot

changeset-bot Bot commented Jun 4, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b3b2571

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codspeed-hq

codspeed-hq Bot commented Jun 4, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 189 untouched benchmarks
⏩ 120 skipped benchmarks1


Comparing feat/react-compiler (b3b2571) with main (677305b)

Open in CodSpeed

Footnotes

  1. 120 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@kdy1 kdy1 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@magic-akari magic-akari force-pushed the feat/react-compiler branch from d3a25d2 to 871eddb Compare June 7, 2026 06:31
@magic-akari magic-akari changed the base branch from main to fix/codegen-export-as-namespace June 7, 2026 06:32
kdy1 pushed a commit that referenced this pull request Jun 7, 2026
Base automatically changed from fix/codegen-export-as-namespace to main June 7, 2026 07:19
@magic-akari magic-akari force-pushed the feat/react-compiler branch from 548bc1a to 78acfef Compare June 7, 2026 07:35
@magic-akari

Copy link
Copy Markdown
Member Author

Still working on this.

@magic-akari magic-akari force-pushed the feat/react-compiler branch from 78acfef to 6e42318 Compare June 13, 2026 11:01
@socket-security

socket-security Bot commented Jun 13, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedcargo/​forked_react_compiler@​0.1.510010093100100
Addedcargo/​forked_react_compiler_ast@​0.1.59910093100100
Addedcargo/​forked_react_compiler_hir@​0.1.510010093100100

View full report

@magic-akari magic-akari force-pushed the feat/react-compiler branch 4 times, most recently from 4dc33fb to a3d28ed Compare June 13, 2026 12:08
@magic-akari magic-akari marked this pull request as ready for review June 13, 2026 12:38
@magic-akari magic-akari requested review from a team as code owners June 13, 2026 12:38

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a3d28ed826

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread crates/swc_ecma_react_compiler/src/convert_ast_reverse.rs
Comment thread crates/swc_ecma_react_compiler/src/lib.rs
Comment thread crates/swc/src/config/mod.rs
Comment thread crates/swc_ecma_react_compiler/src/convert_scope.rs Outdated
Comment thread crates/swc_ecma_react_compiler/src/convert_scope.rs Outdated
Comment thread crates/swc/src/config/mod.rs Outdated
Comment thread crates/swc/src/config/mod.rs Outdated
@kdy1

kdy1 commented Jun 13, 2026

Copy link
Copy Markdown
Member

@magic-akari Can you reflect the unresolved review items? You can mark them as resolved if those are not correct

@CPunisher

Copy link
Copy Markdown
Member

ScopeCollector overlaps somewhat with the swc resolver.
oxc directly converts the results of semantic analysis into react compiler ScopeInfo.

In the long run, we should consider merging the swc resolver and ScopeCollector.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2568cfdbc1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread crates/swc_ecma_react_compiler/src/lib.rs
Comment thread crates/swc_ecma_react_compiler/src/apply_renames.rs Outdated
Comment thread crates/swc_ecma_react_compiler/src/convert_ast.rs
Comment thread crates/swc_ecma_react_compiler/src/convert_scope.rs
@CPunisher

CPunisher commented Jun 13, 2026

Copy link
Copy Markdown
Member

The binary size increases by ~5MB:
main: https://github.com/swc-project/swc/actions/runs/27246095890
pr: https://github.com/swc-project/swc/actions/runs/27467879740

This is expected but can probably be further optimized. See oxc-project/oxc#22942 (comment).
One key point is oxc-project/forked-react-compiler#21 to make react compiler return rust struct rather than serialized JSON.

@magic-akari

Copy link
Copy Markdown
Member Author

@magic-akari Can you reflect the unresolved review items? You can mark them as resolved if those are not correct

Done. All issues have been marked as resolved, including two fixes.
I believe some of the problems involving upstream React details cannot be decided on my end, but since we inherited the implementation from the official adapter, I don't have any specific thoughts on it.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c510a6ada8

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread crates/swc_ecma_react_compiler/src/convert_scope.rs Outdated
Comment thread crates/swc_ecma_react_compiler/src/convert_scope.rs
Comment thread crates/swc_ecma_react_compiler/src/convert_scope.rs Outdated
Comment thread crates/swc_ecma_react_compiler/src/convert_scope.rs Outdated
Comment thread crates/swc_ecma_react_compiler/src/convert_scope.rs Outdated
@magic-akari magic-akari force-pushed the feat/react-compiler branch from 292e7e6 to 7f88b5d Compare June 14, 2026 03:39

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7f88b5dcbe

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread crates/swc_ecma_react_compiler/src/convert_scope.rs Outdated
Comment thread crates/swc_ecma_react_compiler/src/apply_renames.rs
Comment thread crates/swc_ecma_react_compiler/src/convert_scope.rs Outdated
Comment thread crates/swc_ecma_react_compiler/src/convert_scope.rs
@magic-akari magic-akari force-pushed the feat/react-compiler branch from 7f88b5d to a76a723 Compare June 14, 2026 04:26

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a76a723924

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread crates/swc_ecma_react_compiler/src/convert_ast.rs
Comment thread crates/swc_ecma_react_compiler/src/convert_ast.rs
Comment thread packages/types/index.ts
kdy1
kdy1 previously approved these changes Jun 14, 2026
@kdy1 kdy1 changed the title feat(ecma/react-compiler): Add React Compiler feat(es/react-compiler): Add React Compiler Jun 14, 2026
@kdy1 kdy1 enabled auto-merge (squash) June 14, 2026 23:56

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b3b2571b20

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

ScopeFlags::Class | ScopeFlags::StrictMode,
class_decl.class.span,
);
class_decl.class.visit_children_with(self);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep static-block vars scoped to the block

When a class contains a static {} block, this default class traversal reaches the static block as an ordinary block under the class scope; var declarations inside it then use enclosing_function_scope() and get registered in the outer program/function scope. For inputs like const x = 1; class C { static { var x = 2; } } function App() { return x; }, ScopeInfo can resolve App's x to the static-block-local var even though static-block vars do not escape, so React Compiler dependency/rename analysis can target the wrong binding; handle StaticBlock with its own var scope before visiting its body.

Useful? React with 👍 / 👎.

}),
Expression::Import(import) => swc::Callee::Import(swc::Import {
span: self.span_from_base(&import.base),
phase: swc::ImportPhase::Evaluation,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve dynamic import phases

For source/defer dynamic imports that pass through this bridge, this hard-coded Evaluation phase turns import.source("foo") or import.defer("foo") into a plain import("foo") after React Compiler is enabled. SWC stores the phase on Callee::Import and codegen uses it to print .source/.defer, so preserve the original phase in the call shell instead of resetting it here.

Useful? React with 👍 / 👎.

if self.declaration_starts.contains(&start) {
return;
}
self.reference_identifier(ident);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Skip intrinsic JSX tags in scope references

When a component/file also has a binding named like an intrinsic tag, for example const div = value; function App() { return <div />; }, SWC's JSXElementName::Ident traversal reaches this catch-all identifier visitor and records the lowercase tag as a reference to that binding. If React Compiler later renames that binding, the span-based rename plan can rewrite preserved JSX to <div_0 />, and even without a rename it adds a spurious dependency; add a JSX element-name visitor that only references component-like names/member objects and skips intrinsic tags.

Useful? React with 👍 / 👎.

Comment on lines +1200 to +1201
for (sym_id, &bind_id) in &symbol_to_binding {
if self.scoping.symbol_name(*sym_id) == name {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Bind default-export refs by declaration span

When another symbol with the same name exists anywhere in the file, this unordered HashMap scan can attach the Babel-style ExportDefaultDeclaration reference for export default function Foo() to the wrong Foo binding. React Compiler consumes this ScopeInfo for export/reference analysis, so a nested or sibling same-named symbol can make the default export nondeterministically point at the wrong binding; use the function ident's declaration span or the current scope instead of a name-only scan.

Useful? React with 👍 / 👎.

@kdy1 kdy1 merged commit b182fbd into main Jun 15, 2026
196 checks passed
@kdy1 kdy1 deleted the feat/react-compiler branch June 15, 2026 00:24
@github-actions github-actions Bot added this to the Planned milestone Jun 15, 2026
kdy1 pushed a commit that referenced this pull request Jun 18, 2026
…ar boundaries (#11943)

**Description:**

This PR fixes scope analysis edge cases in the React Compiler where
`var` declarations and TypeScript constructs were incorrectly hoisted or
leaked across scope boundaries.

**Design Notes:**

`declare` and `global` are TypeScript type-system annotations that don't
affect runtime emission, yet they still create declarations that
downstream code can reference. The analyzer must walk their bodies
normally and create bindings accordingly, rather than skipping
traversal.

**Changes:**

- **Class static blocks as `var` boundaries**  
`var` declarations inside `static { }` blocks are now scoped to the
block itself, matching ECMAScript semantics, instead of leaking into the
enclosing function.

- **TypeScript namespace / module scopes**  
`namespace` and `module` bodies now create proper `TsModuleBlock`
scopes. Their members are no longer incorrectly hoisted to the Program
scope.

- **Consistent binding for `declare enum`**  
`declare enum` is now registered as a local binding so references
resolve correctly.

- **Refactoring**  
Renamed `enclosing_function_scope()` → `enclosing_var_scope()` and
updated `ScopeFlags` definitions to make scope-kind checks clearer.

**Known Limitations:**

**TypeScript namespace merging is not yet supported.** The scope
collector treats each `namespace`/`module` declaration as an isolated
lexical scope. Exported members in one block are not visible to later
merged blocks, and they are modeled as plain local bindings. This is a
similar issue described in #11607.

**BREAKING CHANGE:**

<!--
If this PR introduces a breaking change, it must contain a notice for it
to be included in the CHANGELOG. Add description or remove entirely if
not breaking.

You may need to update `MIGRATION.md` for the breaking changes.
-->

**Related issue (if exists):**
- #11917 (comment)
@kdy1 kdy1 modified the milestones: Planned, v1.15.43 Jun 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants