Skip to content

Commit 9a37c41

Browse files
committed
feat(napi): restructure React transform options (#25326)
Restructure `oxc-transform-react` options around `reactCompiler` and the shared JSX/Fast Refresh configuration. Generated with AI assistance; reviewed and validated by the contributor.
1 parent c391830 commit 9a37c41

6 files changed

Lines changed: 550 additions & 83 deletions

File tree

‎napi/transform-react/README.md‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Native Node.js bindings for Oxc's experimental Rust port of React Compiler.
44

55
The API follows `oxc-transform`: pass a filename, source text, and optional
66
options to either `transformSync` or `transform`. React Compiler runs first,
7-
then Oxc removes TypeScript syntax and lowers JSX.
7+
then Oxc removes TypeScript syntax and applies the configured JSX transforms.
88

99
```javascript
1010
import { transformSync } from "oxc-transform-react";
@@ -17,7 +17,12 @@ const result = transformSync(
1717
}
1818
`,
1919
{
20-
target: "19",
20+
reactCompiler: {
21+
target: "19",
22+
},
23+
jsx: {
24+
runtime: "automatic",
25+
},
2126
},
2227
);
2328

@@ -33,11 +38,16 @@ the downstream transform. Some React Compiler bail-outs have error severity but
3338
are nonfatal under the default `panicThreshold`; check `fatal` to decide whether
3439
the transform emitted usable code.
3540

36-
The React Compiler options use the same names as
41+
`reactCompiler` defaults to `true`. Set it to `false` to skip React Compiler,
42+
or pass an options object using the same names as
3743
`babel-plugin-react-compiler`/`react-compiler-napi`, including
3844
`compilationMode`, `panicThreshold`, `target`, `gating`, `outputMode`,
3945
suppression controls, and the supported `environment` flags.
4046

47+
`jsx` accepts the same options as `oxc-transform`, including automatic or
48+
classic runtime configuration and React Fast Refresh. Set it to `"preserve"`
49+
to leave JSX syntax in the output.
50+
4151
Callback-valued options such as `logger`, function-valued `sources`, and type
4252
provider callbacks are not accepted by the native binding. `sources` accepts
4353
an array of filename substrings instead.

‎napi/transform-react/index.d.ts‎

Lines changed: 137 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,76 @@ export interface SourceMap {
3636
version: number
3737
x_google_ignoreList?: Array<number>
3838
}
39+
/**
40+
* Configure how TSX and JSX are transformed.
41+
*
42+
* @see <https://oxc.rs/docs/guide/usage/transformer/jsx>
43+
*/
44+
export interface JsxOptions {
45+
/**
46+
* Decides which runtime to use.
47+
*
48+
* - 'automatic' - auto-import the correct JSX factories
49+
* - 'classic' - no auto-import
50+
*
51+
* @default 'automatic'
52+
*/
53+
runtime?: 'classic' | 'automatic'
54+
/**
55+
* Emit development-specific information, such as `__source` and `__self`.
56+
*
57+
* @default false
58+
*/
59+
development?: boolean
60+
/**
61+
* Toggles whether or not to throw an error if an XML namespaced tag name
62+
* is used.
63+
*
64+
* Though the JSX spec allows this, it is disabled by default since React's
65+
* JSX does not currently have support for it.
66+
*
67+
* @default true
68+
*/
69+
throwIfNamespace?: boolean
70+
/**
71+
* Mark JSX elements and top-level React method calls as pure for tree shaking.
72+
*
73+
* @default true
74+
*/
75+
pure?: boolean
76+
/**
77+
* Replaces the import source when importing functions.
78+
*
79+
* @default 'react'
80+
*/
81+
importSource?: string
82+
/**
83+
* Replace the function used when compiling JSX expressions. It should be a
84+
* qualified name (e.g. `React.createElement`) or an identifier (e.g.
85+
* `createElement`).
86+
*
87+
* Only used for `classic` {@link runtime}.
88+
*
89+
* @default 'React.createElement'
90+
*/
91+
pragma?: string
92+
/**
93+
* Replace the component used when compiling JSX fragments. It should be a
94+
* valid JSX tag name.
95+
*
96+
* Only used for `classic` {@link runtime}.
97+
*
98+
* @default 'React.Fragment'
99+
*/
100+
pragmaFrag?: string
101+
/**
102+
* Enable React Fast Refresh.
103+
*
104+
* @default false
105+
*/
106+
refresh?: boolean | ReactRefreshOptions
107+
}
108+
39109
/** Dynamic feature-gating import. */
40110
export interface ReactCompilerDynamicGating {
41111
source: string
@@ -97,31 +167,11 @@ export interface ReactCompilerMetaTarget {
97167
}
98168

99169
/**
100-
* Compile a JavaScript or TypeScript React module asynchronously.
170+
* React Compiler options.
101171
*
102-
* This uses a worker-pool thread and can be slower than `transformSync` for a
103-
* single small module.
104-
*/
105-
export declare function transform(filename: string, sourceText: string, options?: TransformOptions | undefined | null): Promise<TransformResult>
106-
107-
/**
108-
* Options for compiling a JavaScript or TypeScript React module.
109-
*
110-
* React Compiler fields mirror `babel-plugin-react-compiler` and
111-
* `react-compiler-napi`. `lang`, `sourceType`, and `sourcemap` configure the
112-
* surrounding Oxc parse/codegen pipeline.
172+
* Fields mirror `babel-plugin-react-compiler` and `react-compiler-napi`.
113173
*/
114-
export interface TransformOptions {
115-
/** Treat the source as `js`, `jsx`, `ts`, `tsx`, or `dts`. */
116-
lang?: 'js' | 'jsx' | 'ts' | 'tsx' | 'dts'
117-
/** Treat the source as script, module, CommonJS, or infer it from syntax. */
118-
sourceType?: 'script' | 'module' | 'commonjs' | 'unambiguous'
119-
/**
120-
* Generate a source map.
121-
*
122-
* @default false
123-
*/
124-
sourcemap?: boolean
174+
export interface ReactCompilerOptions {
125175
/**
126176
* Which functions the compiler attempts to compile.
127177
*
@@ -184,6 +234,68 @@ export interface TransformOptions {
184234
environment?: ReactCompilerEnvironmentOptions
185235
}
186236

237+
/** React Fast Refresh options. */
238+
export interface ReactRefreshOptions {
239+
/**
240+
* Specify the identifier of the refresh registration variable.
241+
*
242+
* @default `$RefreshReg$`
243+
*/
244+
refreshReg?: string
245+
/**
246+
* Specify the identifier of the refresh signature variable.
247+
*
248+
* @default `$RefreshSig$`
249+
*/
250+
refreshSig?: string
251+
/**
252+
* Emit full hook signatures instead of compact hashes.
253+
*
254+
* @default false
255+
*/
256+
emitFullSignatures?: boolean
257+
}
258+
259+
/**
260+
* Compile a JavaScript or TypeScript React module asynchronously.
261+
*
262+
* This uses a worker-pool thread and can be slower than `transformSync` for a
263+
* single small module.
264+
*/
265+
export declare function transform(filename: string, sourceText: string, options?: TransformOptions | undefined | null): Promise<TransformResult>
266+
267+
/**
268+
* Options for compiling a JavaScript or TypeScript React module.
269+
*
270+
* `lang`, `sourceType`, and `sourcemap` configure the surrounding Oxc
271+
* parse/codegen pipeline. React Compiler and JSX transforms are configured
272+
* independently.
273+
*/
274+
export interface TransformOptions {
275+
/** Treat the source as `js`, `jsx`, `ts`, `tsx`, or `dts`. */
276+
lang?: 'js' | 'jsx' | 'ts' | 'tsx' | 'dts'
277+
/** Treat the source as script, module, CommonJS, or infer it from syntax. */
278+
sourceType?: 'script' | 'module' | 'commonjs' | 'unambiguous'
279+
/**
280+
* Generate a source map.
281+
*
282+
* @default false
283+
*/
284+
sourcemap?: boolean
285+
/**
286+
* Configure how TSX and JSX are transformed, or preserve JSX syntax.
287+
*
288+
* @see <https://oxc.rs/docs/guide/usage/transformer/jsx>
289+
*/
290+
jsx?: 'preserve' | JsxOptions
291+
/**
292+
* Configure React Compiler, or disable it with `false`.
293+
*
294+
* @default true
295+
*/
296+
reactCompiler?: boolean | ReactCompilerOptions
297+
}
298+
187299
/** Result returned by the React Compiler transform. */
188300
export interface TransformResult {
189301
/** Whether the transform was aborted without emitting code. */
@@ -204,7 +316,7 @@ export interface TransformResult {
204316
/**
205317
* Compile a JavaScript or TypeScript React module synchronously.
206318
*
207-
* The React Compiler runs first on the pristine AST. TypeScript and JSX are
208-
* lowered afterwards, matching the transform pipeline used by `oxc-transform`.
319+
* The React Compiler runs first on the pristine AST. TypeScript syntax is
320+
* removed and configured JSX transforms run afterwards.
209321
*/
210322
export declare function transformSync(filename: string, sourceText: string, options?: TransformOptions | undefined | null): TransformResult

‎napi/transform-react/src/lib.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,8 @@ fn error_result(filename: &str, source_text: &str, diagnostics: Diagnostics) ->
149149

150150
/// Compile a JavaScript or TypeScript React module synchronously.
151151
///
152-
/// The React Compiler runs first on the pristine AST. TypeScript and JSX are
153-
/// lowered afterwards, matching the transform pipeline used by `oxc-transform`.
152+
/// The React Compiler runs first on the pristine AST. TypeScript syntax is
153+
/// removed and configured JSX transforms run afterwards.
154154
#[napi]
155155
pub fn transform_sync(
156156
filename: String,

0 commit comments

Comments
 (0)