Visitar URL original
feat(es/parser): add opt-in parser-only TSRX lowering by trueadm · Pull Request #12120 · swc-project/swc · GitHub
Skip to content

feat(es/parser): add opt-in parser-only TSRX lowering - #12120

Merged
Donny/강동윤 (kdy1) merged 9 commits into
swc-project:mainfrom
trueadm:codex/tsrx-parser
Aug 24, 2026
Merged

Donny/강동윤 (kdy1) merged 9 commits into
swc-project:mainfrom
trueadm:codex/tsrx-parser

Conversation

@trueadm

@trueadm Dominic Gannaway (trueadm) commented Aug 14, 2026 •

Copy link
Copy Markdown
Contributor

Description:

This rewrites the initial TSRX implementation as an opt-in, parser-only lowering instead of extending swc_ecma_ast.

The parser recognizes TSRX through the default-disabled swc_ecma_parser/tsrx Cargo feature and immediately lowers the syntax to existing TypeScript/JSX AST nodes. As a result, the shared AST, generated visitors, codegen, transforms, JavaScript bindings, WASM bindings, configuration schema, and filename-based defaults remain unchanged.

Rust facade exposure is intentionally limited to:

  • swc_ecmascript/tsrx-parser
  • swc_core/ecma_parser_tsrx

Most TSRX-specific behavior lives in swc_ecma_parser/src/parser/tsrx.rs, including parser-private IR, validation, standard AST construction, React helper tracking, collision-safe generated identifiers, conditional import injection, and JSX directive handling. The lexer and existing parser modules contain only feature-gated delegation and JSX rescanning hooks. With the feature disabled, the TSRX parser state and the JSX @ scan path are not compiled.

TSRX is defined as module-only syntax. parse_module and parse_program are supported, and parse_program always returns a module when TSRX is enabled. Script/CommonJS and standalone-expression entry points report dedicated diagnostics when TSRX syntax is used.

The lowering covers:

  • direct function @{ setup; render } bodies and expression @{} IIFEs
  • @if conditionals, using branch IIFEs only when setup statements require them
  • classic for, for-in, for-of, and for-await loops with preserved break/continue, per-iteration index bindings, key handling, and entered-state-based @empty
  • @switch with fallthrough and explicit break behavior preserved
  • @try content components with optional React Suspense, TsrxErrorBoundary, catch/reset patterns, setup statements, and synchronous JavaScript finally
  • single-evaluation dynamic tag aliases
  • JSX prop shorthand normalization
  • raw <style> bodies represented as ordinary JSX string expression children

Required React helpers are inserted after directive prologues and only when used. Generated bindings avoid source-level name collisions and use a separate SyntaxContext.

This deliberately does not implement hook analysis, helper/static hoisting, scoped CSS extraction, or optimization parity with the canonical @tsrx/react compiler. In particular, @finally follows synchronous JavaScript try/finally semantics and does not model a Suspense asynchronous lifetime.

Validation includes feature-gated fixture snapshots for the full syntax surface, comments/trivia, nested JSX, all loop forms, switch behavior, try/pending/catch/reset/finally, helper import placement, name collisions, module-only diagnostics, and invalid syntax. Lowered TSX snapshots are reparsed by the regular TSX parser, and serialized AST checks ensure no TSRX-specific public node types are emitted.

Checks run locally:

  • cargo fmt --all -- --check
  • cargo clippy --all --all-targets -- -D warnings
  • cargo clippy -p swc_ecma_parser --no-default-features --features tsrx --all-targets -- -D warnings
  • TSRX fixture tests with and without snapshot updates
  • feature-disabled JSX fixture tests
  • cargo test -p swc_ecmascript --no-default-features --features tsrx-parser
  • cargo test -p swc_core --no-default-features --features ecma_parser_tsrx
  • parser benchmark comparison against the PR base with the TSRX feature disabled; Criterion detected no performance change

The full parser suite was also run with both typescript and tsrx. The existing errors_tests__typescript_errors__type_only_import_specifier__invalid_type_only__input_ts fixture fails identically in both configurations; all TSRX-specific tests pass.

Related issue (if exists):

N/A

@changeset-bot

changeset-bot Bot commented Aug 14, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c8cb07a

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

@CLAassistant

CLAassistant commented Aug 14, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@codspeed

codspeed Bot commented Aug 14, 2026 •

Copy link
Copy Markdown

Merging this PR will regress 1 benchmark

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
❌ 1 regressed benchmark
✅ 198 untouched benchmarks
⏩ 61 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ Simulation es/minifier/libs/d3 365.3 ms 373 ms -2.05%
⚡ Simulation es/large/minify/libraries/d3 485.3 ms 474.9 ms +2.17%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing trueadm:codex/tsrx-parser (c8cb07a) with main (3802924)2

Open in CodSpeed

Footnotes

  1. 61 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. ↩

  2. No successful run was found on main (a491792) during the generation of this report, so 3802924 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩

Copy link
Copy Markdown

Review of TSRX parser/AST support

Reviewed commit 1249697fcafdc719c6978f1bd8748d9f9febfda6 against the existing SWC APIs and the canonical TSRX parser used by Ripple/Octane. The follow-up commits correctly fix ordinary-JSX shorthand: false serialization and add the required major-version Cargo changeset. The following issues remain.

1. Current plugin CI fails with an unhandled unknown AST variant

The current plugin-backend job fails with:

error[E0004]: non-exhaustive patterns:
`&mut TsrxExpr::Unknown(_, _)` not covered
--> crates/swc_ecma_ast/src/expr.rs:419:36

The nested match in Expr::set_span does not handle the generated unknown variant when plugin builds enable swc_ast_unknown and encoding-impl. Add the same conditional fallback already used by the enclosing match:

#[cfg(all(swc_ast_unknown, feature = "encoding-impl"))]
_ => swc_common::unknown!(),

2. Published JavaScript AST types and visitor do not support the returned nodes

@swc/types adds tsrx?: boolean but does not define the TSRX AST interfaces, add TSRX nodes to Expression / JSXElementChild, add JSXExpressionContainer to JSXElementName, or expose the JSXAttribute.shorthand field.

The existing @swc/core visitor is also unchanged. Executing it against nodes from the committed TSRX fixtures produces:

visitExpression(JSXCodeBlock)               -> undefined
visitJSXElementChild(JSXIfExpression)       -> undefined
visitJSXElementName(JSXExpressionContainer) -> undefined

Because visitor callers assign those results back into the AST, valid directive children and dynamic tag names are silently replaced with undefined. Please add the public node types, visitor dispatch/traversal, and JS-facing parse/visit regression tests.

3. The serialized AST is not compatible with the canonical TSRX / Octane contract

Construct Existing TSRX/Octane shape This PR
function Component() @{ ... } fn.body.type === "JSXCodeBlock" FunctionBody wrapping a JSXCodeBlock expression
@for await await isAwait
@catch (error, reset) handler.resetParam handler.reset

See the new AST definitions and catch-clause shape. The isAwait spelling also conflicts with SWC's existing ForOfStmt, which explicitly serializes is_await as await. If this parser is intended to feed existing TSRX/Octane tooling, align these shapes or define and test an explicit adapter.

4. JSX text containing directive-like words is incorrectly tokenized

is_tsrx_directive_start treats @if, @for, @switch, and @try followed by any nonidentifier character as directives. Valid text such as:

<div>@if</div>
<div>contact@if.com</div>
<div>@try me</div>

is therefore routed into directive parsing. The canonical TSRX parser accepts these as JSXText; it only recognizes a directive when the next non-whitespace token has the required ( or { shape.

5. Minified @else if becomes invalid @elseif

The TSRX code generator uses formatting_space! between else and a nested if. That space disappears when minifying:

@if (a) { <A /> } @else if (b) { <B /> }
// currently minifies to: @if(a){<A/>}@elseif(b){<B/>}

Use mandatory space! for this token boundary and add a minified @else if round-trip regression.

6. Template loop/switch bodies miss normal break/continue contexts

@for bodies and @switch cases are parsed without the normal IsBreakAllowed / IsContinueAllowed contexts established by ordinary SWC loop/switch parsing. Valid canonical TSRX such as:

@for (const x of xs) { if (x) continue; <A /> }
@switch (x) { @case 1: { if (x) break; <A /> } @default: { <B /> } }

therefore produces loop-control diagnostics.

7. Code-block render validation and source spans are incomplete

parse_tsrx_code_block parses an unrestricted statement block and extracts only its final JSX/directive expression. This incorrectly accepts:

function X() @{ <A />; <B /> }        // first render node silently treated as setup
function X() @{ <A />; const x = 1 } // rendered output silently disappears

The canonical parser rejects both: code blocks contain at most one rendered output, and setup cannot follow it. Explicit @{ ... } node spans also start at {, omitting the authored leading @.

8. @try / @catch grammar differs from canonical TSRX

The try parser requires parenthesized identifier-only catch parameters, so it rejects supported forms such as:

@try { <A /> } @catch { <B /> }
@try { <A /> } @catch ({ message }) { <B /> }
@try { <A /> } @catch (error: Error, reset: () => void) { <B /> }

It also incorrectly accepts @try { <A /> } without either @pending or @catch.

9. Additional validation and output regressions

  • Dynamic JSX tags currently accept expressions such as <{getTag()}> and <{1}>, which the canonical TSRX parser rejects.
  • @for accepts invalid await forms and duplicate or misordered index / key options.
  • JSXOpeningElement emission now inserts mandatory spaces before every attribute in every mode. Existing preserved-JSX minification can emit <div a={1}b={2}/>; this change expands it to <div a={1} b={2}/>, growing ordinary JSX output even when TSRX is disabled.

Suggested coverage: plugin builds with swc_ast_unknown, JS parse/type/visitor integration, canonical TSRX AST-shape assertions, literal @if/email JSX text, minified @else if, template break/continue, invalid multiple-render blocks, catch variants, dynamic-tag validation, @for option validation, and unchanged ordinary-JSX minification.

@trueadm
Dominic Gannaway (trueadm) marked this pull request as ready for review August 14, 2026 23:11

@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: f1fcead834

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_codegen/src/tsrx.rs Outdated
Comment thread crates/swc_ecma_parser/src/lexer/state.rs Outdated
Comment thread packages/core/src/index.ts Outdated
Comment thread crates/swc_ecma_visit/src/generated.rs Outdated
Comment thread packages/types/index.ts Outdated
Comment thread packages/core/src/index.ts Outdated
Comment thread crates/swc_ecma_parser/src/parser/tsrx.rs Outdated
Comment thread crates/swc_ecma_parser/src/parser/tsrx.rs

@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: c9fb340b5a

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_visit/src/generated.rs Outdated
Comment thread crates/swc_ecma_ast/src/tsrx.rs Outdated
Comment thread crates/swc_ecma_codegen/src/tsrx.rs Outdated
Comment thread crates/swc_ecma_visit/src/generated.rs Outdated
Comment thread crates/swc_ecma_parser/src/parser/class_and_fn.rs Outdated
Comment thread crates/swc_ecma_codegen/src/stmt.rs Outdated

@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: 9870800562

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_compat_es2015/src/destructuring.rs Outdated
Comment thread crates/swc_ecma_transformer/src/es2017/async_to_generator.rs Outdated
Comment thread crates/swc_ecma_parser/src/parser/class_and_fn.rs Outdated
Comment thread crates/swc_ecma_codegen/src/tsrx.rs Outdated
Comment thread crates/swc_ecma_codegen/src/jsx.rs Outdated

@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: 77bcad32af

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_transforms_base/src/resolver/mod.rs Outdated
Comment thread bindings/binding_core_wasm/src/types.rs Outdated
Comment thread packages/core/src/Visitor.ts Outdated
Comment thread packages/core/src/index.ts Outdated
Comment thread packages/types/index.ts Outdated

@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: 882c0f6f46

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_codegen/src/tsrx.rs Outdated
Comment thread crates/swc_ecma_react_compiler/src/convert_ast.rs Outdated
Comment thread crates/swc_ecma_ast/src/jsx.rs Outdated
Comment thread crates/swc_ecma_transforms_react/src/jsx/mod.rs Outdated

@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: 27b0988101

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_minifier/src/util/size.rs Outdated
Comment thread crates/swc_ecma_parser/src/parser/jsx.rs
Comment thread crates/swc_ecma_codegen/src/lib.rs Outdated

@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: 87e149ae14

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_react_compiler/src/prefilter.rs Outdated
Comment thread crates/swc_ecma_parser/src/parser/expr.rs Outdated
Comment thread crates/swc_cli_impl/src/commands/compile.rs Outdated

@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: 68ddc3798e

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_parser/src/parser/tsrx.rs Outdated
Comment thread crates/swc_ecma_visit/src/generated.rs Outdated
Comment thread crates/swc_ecma_transforms_base/src/resolver/mod.rs Outdated

@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: 5ca034cfed

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_codegen/src/lib.rs Outdated
Comment thread crates/swc_ecma_visit/src/generated.rs Outdated
Comment thread crates/swc_ecma_parser/src/lexer/state.rs Outdated

@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: 2b9dfc69eb

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_codegen/src/tsrx.rs Outdated

@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: 1053d51bac

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_parser/src/parser/class_and_fn.rs
Comment thread crates/swc_ecma_compat_es2015/src/block_scoping/mod.rs Outdated
Comment thread crates/swc_ecma_ast/src/jsx.rs Outdated
Comment thread crates/swc_ecma_visit/src/generated.rs Outdated

@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: a415614f05

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_minifier/src/usage_analyzer/analyzer/mod.rs Outdated
Comment thread crates/swc_ecma_visit/src/generated.rs Outdated
Comment thread crates/swc_ecma_visit/src/generated.rs Outdated
Comment thread crates/swc_ecma_ast/src/tsrx.rs Outdated

@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: 29f133eac5

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_minifier/src/usage_analyzer/analyzer/mod.rs Outdated

@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: f0238126e2

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_codegen/src/lib.rs Outdated
Comment thread crates/swc_ecma_codegen/src/lib.rs Outdated
Comment thread crates/swc_ecma_visit/src/generated.rs Outdated

@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: 2403b9ead2

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread packages/core/src/index.ts
Comment thread crates/swc_ecma_compat_es2015/src/generator.rs Outdated
Comment thread crates/swc_ecma_ast/src/tsrx.rs Outdated

@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: 3d20ab939d

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_codegen/src/lib.rs Outdated
Comment thread crates/swc_ecma_transforms_module/src/rewriter/import_rewriter_typescript.rs Outdated
Comment thread crates/swc_ecma_ast/src/tsrx.rs Outdated
Comment thread crates/swc_ecma_ast/src/tsrx.rs Outdated

@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: 3fdd5d3633

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_parser/src/parser/class_and_fn.rs
Comment thread crates/swc_ecma_parser/src/parser/jsx.rs

@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: 71a0dcfac9

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_compat_es2015/src/generator.rs Outdated
Comment thread packages/core/src/index.ts Outdated
Comment thread crates/swc_ecma_parser/src/lexer/state.rs Outdated

@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: 17fdd91685

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_compat_es2015/src/generator.rs Outdated
Comment thread crates/swc_ecma_compat_es2015/src/generator.rs Outdated
Comment thread crates/swc_ecma_compat_es2015/src/generator.rs Outdated
Comment thread crates/swc_ecma_compat_es2015/src/generator.rs Outdated

@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: a158205885

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_compat_es2015/src/generator.rs Outdated
Comment thread crates/swc_ecma_hooks/src/generated.rs Outdated

@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: 0ccfada3a9

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_visit/src/generated.rs Outdated
Comment thread crates/swc_ecma_compat_es2015/src/generator.rs Outdated
Comment thread crates/swc_ecma_compat_es2015/src/generator.rs Outdated
Comment thread crates/swc_ecma_compat_es2015/src/generator.rs Outdated
Comment thread crates/swc_ecma_parser/src/parser/jsx.rs Outdated

@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: dbdfd622b1

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_compat_es2015/src/generator.rs Outdated
Comment thread crates/swc_ecma_compat_es2015/src/classes/mod.rs Outdated
@kdy1

Copy link
Copy Markdown
Member

Thank you for putting this together and for the substantial work behind it.

At this point, we don't think TSRX has the level of adoption needed for SWC to support it as a first-class syntax on the same level as JSX. Supporting new syntax at the parser and AST level carries significant long-term maintenance and ecosystem costs, so TSRX would need to become comparably well-known and widely used before we could consider this level of support.

For clarification, parser-level stripping is a special-case feature that we provide only for Flow. It should not be considered a general extension point or precedent for supporting other syntax dialects.

Given that, we're going to close this PR for now. If TSRX gains substantially broader adoption in the future, we can revisit the discussion. Thank you again for the proposal and all the effort you put into it.

@github-actions github-actions Bot added this to the Planned milestone Aug 16, 2026
@trueadm

Copy link
Copy Markdown
Contributor Author

At this point, we don't think TSRX has the level of adoption needed for SWC to support it as a first-class syntax on the same level as JSX. Supporting new syntax at the parser and AST level carries significant long-term maintenance and ecosystem costs, so TSRX would need to become comparably well-known and widely used before we could consider this level of support.

Thank you for reviewing this PR.

I disagree that TSRX needs the same level of adoption as JSX. That's simply not attainable, it's actually impossible. There are literally hundreds of billions of JSX/TSX modules on Github. With AI that will only continue to explode. By not helping an exciting project, just like how others helped SWC grow at the beginning by supporting SWC in their toolchain (such as rspack), you're denying us a valid route into helping TSRX become viable for large enterprise monorepos where there are likely to be thousands of TSRX modules and where build times are paramount. We offered to maintain the code and have it behind a feature flag too – but I guess there's still too much maintenance burden.

You and the team have done some fantastic work, and I remember our healthy discussions on these topics whilst we worked together at Vercel. I look forward to re-visiting this in the future if possible. You've gotta help the small-fish every once in a while, because once upon a time SWC was the small fish too.

@chenjiahan

Copy link
Copy Markdown
Contributor

I think TSRX has a lot of potential, and at the same time, I can understand Donny/강동윤 (@kdy1)'s concerns around long-term maintenance and binary size.

I guess a custom Rspack loader or Rsbuild plugin could be a practical alternative. It would only process .tsrx files, so the impact on overall build performance should be limited. The loader only needs to transform TSRX syntax, with the resulting code continuing through builtin:swc-loader.

As an independent compilation step, the loader could be implemented using either Oxc or SWC and evolve separately. This would give TSRX a practical integration path today while leaving the door open to native support in the future.

@kdy1

Copy link
Copy Markdown
Member

Reopening for personal experiments

@kdy1 Donny/강동윤 (kdy1) changed the title feat(parser): add initial TSRX AST and syntax support feat(es/parser): add opt-in parser-only TSRX lowering Aug 19, 2026

@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: 187e9adbcf

ℹ️ 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 (@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 (@codex) address that feedback".

Comment thread crates/swc_ecma_parser/src/parser/tsrx.rs Outdated
Comment thread crates/swc_ecma_parser/src/parser/tsrx.rs Outdated
Comment thread crates/swc_ecma_parser/src/parser/tsrx.rs Outdated
Comment thread crates/swc_ecma_parser/src/parser/tsrx.rs Outdated
Comment thread crates/swc_ecma_parser/src/parser/tsrx.rs Outdated
Comment thread crates/swc_ecma_parser/src/parser/tsrx.rs Outdated

@kdy1 Donny/강동윤 (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.

I think it's almost good. Need to verify a bit more though

@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: c8cb07a08e

ℹ️ 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 (@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 (@codex) address that feedback".

let suspension = self.suspension_context();
let is_async = suspension.is_async() || requires_async;
let callee = if suspension.is_generator() {
Box::new(Expr::Fn(FnExpr {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve lexical bindings in generator directive IIFEs

When a generator or async-generator method uses an IIFE-requiring directive such as @for or a setup-bearing @if, this branch moves the directive into a plain function* invoked without a receiver. References that were lexical in the source therefore change meaning: this becomes undefined, arguments refers to the empty inner call, and super may be emitted inside a non-method function as invalid syntax. Preserve or explicitly forward the enclosing bindings while retaining the required yield* delegation.

Useful? React with 👍 / 👎.

match expr {
Expr::Ident(_) | Expr::Lit(Lit::Str(_)) => true,
Expr::Tpl(template) => template.exprs.is_empty(),
Expr::Member(member) => Self::is_valid_tsrx_dynamic_element_name(&member.obj),

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 Accept this-rooted member expressions as dynamic tags

When a class method uses an instance component registry, such as <{this.Components.Row}></{this.Components.Row}>, the outer node is a member expression but this recursion eventually reaches Expr::This, which has no accepted arm, and reports the tag as unsupported. This rejects a valid member-expression tag despite the diagnostic explicitly allowing member expressions; permit this as a terminal root while retaining the restrictions on calls.

Useful? React with 👍 / 👎.

let mut fallback_stmts = handler.body.body;
fallback_stmts.push(return_stmt(handler.body.render.unwrap_or_else(null_expr)));
let fallback =
self.arrow_expr(handler.body.span, vec![error, reset], fallback_stmts, false);

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 Reject duplicate catch callback bindings

When both TSRX catch slots bind the same name, as in @catch (error, error) { <Failure /> }, these independently parsed patterns are placed directly into one synthesized arrow without running formal-parameter duplicate-name validation. The accepted source therefore lowers to (error, error) => ..., which is invalid arrow-function syntax when the generated TSX is reparsed; validate the combined bound names before constructing the fallback.

Useful? React with 👍 / 👎.


let mut body = vec![assign_stmt(entered.clone(), true.into())];
if let (Some(index), Some(counter)) = (directive.index, counter) {
body.push(var_stmt(

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 Validate index bindings against loop-body declarations

When an indexed loop body redeclares the option name, for example @for (const item of items; index i) { const i = 1; <Row /> }, this synthesized let i is inserted into the same generated block as the original declaration. The parser accepts the source but codegen produces duplicate lexical declarations and thus invalid TSX; diagnose the collision or preserve separate scopes when introducing the index binding.

Useful? React with 👍 / 👎.

@kdy1
Donny/강동윤 (kdy1) enabled auto-merge (squash) August 24, 2026 06:36
@kdy1
Donny/강동윤 (kdy1) merged commit 61ff097 into swc-project:main Aug 24, 2026
120 checks passed
@github-actions github-actions Bot modified the milestones: Planned, v1.16.2 Sep 11, 2026
Donny/강동윤 (kdy1) added a commit that referenced this pull request Oct 3, 2026
<!-- Note: CI script will automatically rebase your PR so please do not
rebase unless required -->

**Description:**

Add `trueadm` to a dedicated `tsrx` contributor group so TSRX pull
requests and CI runs are accepted by the contributor policy. The account
is identified by the TSRX introduction commit `61ff097706` and merged PR
#12120.

Extend the existing contributor-policy fixtures to verify that `trueadm`
and `TRUEADM` are allowed in the `tsrx` group without repository
permission lookups. Also assert that the repository allowlist contains
the account in that group.

No Rust crates or release metadata are affected, so no release changeset
is needed.

Validation:

- Initialized submodules with `git submodule update --init --recursive`.
- Ran `npm ci --ignore-scripts --no-audit --no-fund` and `npm test` in
`.github/actions/contributor-policy` under Node.js 24; all 89 tests
passed.
- `cargo fmt --all` passed.
- `cargo clippy --all --all-targets -- -D warnings` passed.
- `git diff --check` passed.

**Related issue (if exists):**

Follow-up to #12463 and #12467; TSRX implementation: #12120.
@swc-project swc (swc-project) locked as resolved and limited conversation to collaborators Oct 11, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Development

Successfully merging this pull request may close these issues.

5 participants