@stylexswc/rs-compiler 0.17.0 → 0.17.1-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,260 +1,138 @@
1
- # NAPI-RS compiler for StyleX (\*\*unofficial)
1
+ # @stylexswc/rs-compiler
2
2
 
3
- > Part of the
3
+ > High-performance StyleX compiler for Node.js, written in Rust on NAPI-RS and
4
+ > SWC. Part of the
4
5
  > [StyleX SWC Plugin](https://github.com/Dwlad90/stylex-swc-plugin#readme)
5
- > workspace
6
+ > workspace.
6
7
 
7
8
  <!-- stylex-compatibility:start -->
9
+
8
10
  > [!NOTE]
9
11
  > Compatibility target: this package has been updated through official
10
12
  > StyleX v0.19.0. This is not an official Meta support guarantee.
11
- <!-- stylex-compatibility:end -->
12
-
13
- StyleX is a JavaScript library developed by Meta for defining styles optimized
14
- for user interfaces. You can find the
15
- [official StyleX repository](https://www.github.com/facebook/stylex) here.
16
13
 
17
- > [!WARNING]
18
- > This is an unofficial style compiler for StyleX.
19
-
20
- ## Overview
21
-
22
- This package provides an unofficial, high-performance NAPI-RS compiler for
23
- StyleX, a popular library from Meta for building optimized user interfaces. It
24
- is the top-level consumer crate that exposes the full StyleX pipeline to
25
- Node.js, leveraging SWC for parsing and transformation.
26
-
27
- > [!IMPORTANT]
28
- > The usage of StyleX does not change. All changes are internal.
29
-
30
- - Faster Build Times: By utilizing SWC instead of Babel, you can potentially
31
- experience significant speed improvements during StyleX processing.
32
- - Seamless Integration: This compiler seamlessly integrates with Next.js's
33
- default SWC Compiler, ensuring a smooth workflow.
34
- - Drop-in Replacement: Designed to be a drop-in replacement for the official
35
- StyleX Babel plugin, minimizing disruption to existing codebases.
36
- - Advanced Tooling Capabilities: NAPI-RS compiler unlocks access to StyleX
37
- metadata and source maps, enabling the creation of advanced plugins and tools
38
- for StyleX, ex. for creating a plugin for Webpack, Rollup, or other tools.
39
-
40
- ## Advantages of a `NAPI-RS` compiler versus a `SWC plugin`
41
-
42
- - Compability with SWC: under the hood, the NAPI-RS compiler uses SWC for
43
- parsing and transforming JavaScript code, ensuring compatibility with the
44
- latest ECMAScript features.
45
- - Direct Access to Node.js APIs: NAPI-RS allows you to directly access Node.js
46
- APIs from your Rust code, providing greater flexibility and control.
47
- - Improved Performance: NAPI-RS can often offer better performance than
48
- traditional Node.js addons, especially for computationally intensive tasks.
49
- - Simplified Development: NAPI-RS simplifies the process of developing Node.js
50
- addons in Rust, making it easier to create high-performance and efficient
51
- tools.
52
-
53
- ## Architecture
54
-
55
- - **Layer**: 9 — Compilers (top-level consumer)
56
- - **Depends on**: `stylex-ast`, `stylex-enums`, `stylex-logs`, `stylex-macros`,
57
- `stylex-regex`, `stylex-structures`, `stylex-transform`, `stylex-types`,
58
- `stylex-utils`
59
- - **Depended on by**: None (top-level entry point)
60
-
61
- ### Public API
62
-
63
- - `transform()` — Main entry point: takes source code + options, returns
64
- transformed output
65
- - `should_transform_file()` — File filtering based on path patterns
66
- - `normalize_rs_options()` — Options normalization and validation
67
-
68
- ### Modules
69
-
70
- - `enums` — Compiler-specific enum types
71
- - `structs` — Compiler-specific struct types
72
- - `utils::fn_parser` — Function argument parsing
73
- - `utils::metadata` — Build metadata handling
74
- - `utils::path_filter` — File path filtering logic
75
-
76
- ## Dependency Graph
77
-
78
- <details>
79
- <summary><h3>Dependency Graph</h3></summary>
80
-
81
- ```mermaid
82
- graph TD
83
- subgraph L0["Primitives"]
84
- stylex_constants["constants"]
85
- stylex_regex["regex"]
86
- stylex_styleq["styleq"]
87
- stylex_utils["utils"]
88
- end
89
-
90
- subgraph L1["Proc Macros"]
91
- stylex_macros["macros"]
92
- end
93
-
94
- subgraph L2["Domain Leaves"]
95
- stylex_enums["enums"]
96
- stylex_js["js"]
97
- stylex_logs["logs"]
98
- stylex_css_parser["css-parser"]
99
- stylex_path_resolver["path-resolver"]
100
- end
101
-
102
- subgraph L3["Core Data Structures"]
103
- stylex_structures["structures"]
104
- end
105
-
106
- subgraph L4["Type System"]
107
- stylex_types["types"]
108
- end
109
-
110
- subgraph L5["AST Foundations"]
111
- stylex_ast["ast"]
112
- end
113
-
114
- subgraph L6["Evaluation"]
115
- stylex_evaluator["evaluator"]
116
- end
117
-
118
- subgraph L7["CSS Processing"]
119
- stylex_css["css"]
120
- end
121
-
122
- subgraph L8["StyleX Transform"]
123
- stylex_transform["transform"]
124
- end
125
-
126
- subgraph L9["Compilers"]
127
- stylex_compiler_rs["rs-compiler"]
128
- end
129
-
130
- stylex_utils --> stylex_regex
131
-
132
- stylex_macros --> stylex_constants
133
-
134
- stylex_enums --> stylex_macros
135
- stylex_js --> stylex_constants
136
- stylex_js --> stylex_macros
137
- stylex_logs --> stylex_macros
138
- stylex_css_parser --> stylex_macros
139
- stylex_path_resolver --> stylex_macros
140
-
141
- stylex_structures --> stylex_constants
142
- stylex_structures --> stylex_enums
143
- stylex_structures --> stylex_macros
144
-
145
- stylex_types --> stylex_constants
146
- stylex_types --> stylex_enums
147
- stylex_types --> stylex_macros
148
- stylex_types --> stylex_structures
149
- stylex_types --> stylex_utils
150
-
151
- stylex_ast --> stylex_constants
152
- stylex_ast --> stylex_macros
153
- stylex_ast --> stylex_types
154
- stylex_ast --> stylex_utils
155
-
156
- stylex_evaluator --> stylex_ast
157
- stylex_evaluator --> stylex_constants
158
- stylex_evaluator --> stylex_js
159
- stylex_evaluator --> stylex_macros
160
- stylex_evaluator --> stylex_path_resolver
161
- stylex_evaluator --> stylex_types
162
-
163
- stylex_css --> stylex_ast
164
- stylex_css --> stylex_constants
165
- stylex_css --> stylex_css_parser
166
- stylex_css --> stylex_enums
167
- stylex_css --> stylex_evaluator
168
- stylex_css --> stylex_macros
169
- stylex_css --> stylex_regex
170
- stylex_css --> stylex_structures
171
- stylex_css --> stylex_types
172
- stylex_css --> stylex_utils
173
-
174
- stylex_transform --> stylex_ast
175
- stylex_transform --> stylex_constants
176
- stylex_transform --> stylex_css
177
- stylex_transform --> stylex_css_parser
178
- stylex_transform --> stylex_enums
179
- stylex_transform --> stylex_evaluator
180
- stylex_transform --> stylex_logs
181
- stylex_transform --> stylex_macros
182
- stylex_transform --> stylex_path_resolver
183
- stylex_transform --> stylex_regex
184
- stylex_transform --> stylex_structures
185
- stylex_transform --> stylex_styleq
186
- stylex_transform --> stylex_types
187
- stylex_transform --> stylex_utils
188
-
189
- stylex_compiler_rs --> stylex_ast
190
- stylex_compiler_rs --> stylex_enums
191
- stylex_compiler_rs --> stylex_logs
192
- stylex_compiler_rs --> stylex_macros
193
- stylex_compiler_rs --> stylex_regex
194
- stylex_compiler_rs --> stylex_structures
195
- stylex_compiler_rs --> stylex_transform
196
- stylex_compiler_rs --> stylex_types
197
- stylex_compiler_rs --> stylex_utils
198
-
199
- classDef l0 fill:#e8e8e8,stroke:#999,color:#333
200
- classDef l1 fill:#dce8ff,stroke:#6699cc,color:#333
201
- classDef l2 fill:#dcf5dc,stroke:#66aa66,color:#333
202
- classDef l3 fill:#fff3dc,stroke:#cc9933,color:#333
203
- classDef l4 fill:#ffe8dc,stroke:#cc6633,color:#333
204
- classDef l5 fill:#f5dcff,stroke:#9933cc,color:#333
205
- classDef l6 fill:#dcfff5,stroke:#33aaaa,color:#333
206
- classDef l7 fill:#ffdcdc,stroke:#cc3333,color:#333
207
- classDef l8 fill:#fffdc0,stroke:#aaaa33,color:#333
208
- classDef l9 fill:#ffc0c0,stroke:#cc0000,color:#333
209
-
210
- class stylex_constants,stylex_regex,stylex_styleq,stylex_utils l0
211
- class stylex_macros l1
212
- class stylex_enums,stylex_js,stylex_logs,stylex_css_parser,stylex_path_resolver l2
213
- class stylex_structures l3
214
- class stylex_types l4
215
- class stylex_ast l5
216
- class stylex_evaluator l6
217
- class stylex_css l7
218
- class stylex_transform l8
219
- class stylex_compiler_rs l9
220
- ```
14
+ <!-- stylex-compatibility:end -->
221
15
 
222
- </details>
16
+ [StyleX](https://stylexjs.com) is Meta's CSS-in-JS library with compile-time
17
+ style extraction. The official toolchain compiles it with a Babel plugin; this
18
+ package is a from-scratch Rust implementation of that same transform, exposed to
19
+ Node.js as a native addon through [NAPI-RS](https://napi.rs) and parsed with
20
+ [SWC](https://swc.rs). It is designed as a drop-in replacement: your StyleX code
21
+ and its output do not change, but transforms run 2x to 5x faster than
22
+ Babel — see
23
+ [performance](https://github.com/Dwlad90/stylex-swc-plugin#performance).
24
+
25
+ This is a community project and is not affiliated with or supported by Meta. It
26
+ requires Node.js 20 or newer; prebuilt binaries ship for macOS, Linux (glibc and
27
+ musl), and Windows on x64 and arm64.
28
+
29
+ Most projects should not call this package directly — use the integration for
30
+ your build tool, all of which drive this compiler under the hood:
31
+
32
+ | Build tool | Package |
33
+ | --------------------------------------- | -------------------------------------------------------------------------------------- |
34
+ | Next.js (Webpack, Rspack, Turbopack) | [`@stylexswc/nextjs-plugin`](https://www.npmjs.com/package/@stylexswc/nextjs-plugin) |
35
+ | Vite, esbuild, Farm, Rsbuild, Nuxt, ... | [`@stylexswc/unplugin`](https://www.npmjs.com/package/@stylexswc/unplugin) |
36
+ | webpack | [`@stylexswc/webpack-plugin`](https://www.npmjs.com/package/@stylexswc/webpack-plugin) |
37
+ | Rspack | [`@stylexswc/rspack-plugin`](https://www.npmjs.com/package/@stylexswc/rspack-plugin) |
38
+ | Rollup | [`@stylexswc/rollup-plugin`](https://www.npmjs.com/package/@stylexswc/rollup-plugin) |
39
+ | PostCSS pipelines | [`@stylexswc/postcss-plugin`](https://www.npmjs.com/package/@stylexswc/postcss-plugin) |
40
+ | Jest | [`@stylexswc/jest`](https://www.npmjs.com/package/@stylexswc/jest) |
41
+
42
+ Use this package directly when building your own tooling: custom bundler
43
+ plugins, codemods, or anything that needs the transformed code plus StyleX
44
+ metadata and source maps.
223
45
 
224
46
  ## Installation
225
47
 
226
- To install the package, run the following command:
227
-
228
48
  ```bash
229
49
  npm install --save-dev @stylexswc/rs-compiler
230
50
  ```
231
51
 
232
- ### Transformation Process
52
+ ## Usage
233
53
 
234
- Internally, this compiler takes your StyleX code and transforms it into a format
235
- optimized for further processing.
54
+ The main entry point is `transform`. It takes a filename, the source code, and
55
+ options, and returns the transformed code, metadata about the generated styles,
56
+ and an optional source map:
236
57
 
237
58
  ```ts
238
- var { transform } = require('@stylexswc/rs-compiler');
239
-
240
- /// ...other logic
59
+ const { transform } = require('@stylexswc/rs-compiler');
241
60
 
242
- const { code, metadata, sourcemap } = transform(
61
+ const { code, metadata, map } = transform(
243
62
  filename,
244
63
  inputSourceCode,
245
64
  transformOptions
246
65
  );
66
+ ```
67
+
68
+ ### Example
69
+
70
+ Input StyleX code:
71
+
72
+ ```ts
73
+ import * as stylex from '@stylexjs/stylex';
74
+
75
+ const styles = stylex.create({
76
+ root: {
77
+ padding: 10,
78
+ },
79
+ element: {
80
+ backgroundColor: 'red',
81
+ },
82
+ });
83
+
84
+ export const styleProps = stylex.props(styles.root, styles.element);
85
+ ```
86
+
87
+ Output code:
88
+
89
+ ```ts
90
+ import * as stylex from '@stylexjs/stylex';
91
+ export const styleProps = {
92
+ className: 'x7z7khe xrkmrrc',
93
+ };
94
+ ```
95
+
96
+ ### Output shape
97
+
98
+ Transforming the example above with source maps enabled
99
+ (`sourceMap: SourceMaps.True`) returns:
247
100
 
248
- /// ...other logic
101
+ ```json
102
+ {
103
+ "code": "import * as stylex from '@stylexjs/stylex';\nexport const styleProps = {\n className: \"x7z7khe xrkmrrc\"\n};\n",
104
+ "metadata": {
105
+ "stylex": [
106
+ [
107
+ "x7z7khe",
108
+ {
109
+ "ltr": ".x7z7khe{padding:10px}",
110
+ "rtl": null
111
+ },
112
+ 1000
113
+ ],
114
+ [
115
+ "xrkmrrc",
116
+ {
117
+ "ltr": ".xrkmrrc{background-color:red}",
118
+ "rtl": null
119
+ },
120
+ 3000
121
+ ]
122
+ ]
123
+ },
124
+ "map": "{\"version\":3,\"sources\":[\"app/components/Button.tsx\"],\"names\":[],\"mappings\":\"AAAA;AAWA;;EAAoE\"}"
125
+ }
249
126
  ```
250
127
 
251
- ### Path Filtering
128
+ The `metadata.stylex` rules are what bundler plugins collect to build the final
129
+ CSS file.
130
+
131
+ ## Path Filtering
252
132
 
253
133
  > [!NOTE]
254
- > The `include` and `exclude` options are exclusive to
255
- > this NAPI-RS compiler implementation and are not available in the official
256
- > StyleX Babel plugin. They provide powerful file filtering capabilities to
257
- > control which files are transformed.
134
+ > The `include` and `exclude` options are exclusive to this compiler and
135
+ > are not available in the official StyleX Babel plugin.
258
136
 
259
137
  The compiler exports a `shouldTransformFile` function to determine whether a
260
138
  file should be transformed based on include/exclude patterns:
@@ -273,36 +151,29 @@ if (shouldTransform) {
273
151
  }
274
152
  ```
275
153
 
276
- #### Pattern Types
154
+ ### Pattern Types
277
155
 
278
- - **Glob patterns** (strings): Use standard glob syntax to match file paths
279
- - `src/**/*.tsx` - All `.tsx` files in `src` directory and subdirectories
280
- - `**/*.test.*` - All test files
281
- - `**/node_modules/**` - All files in `node_modules`
156
+ - **Glob patterns** (strings): standard glob syntax matched against file paths
157
+ - `src/**/*.tsx` all `.tsx` files in `src` and subdirectories
158
+ - `**/*.test.*` all test files
159
+ - `**/node_modules/**` all files in `node_modules`
282
160
 
283
- - **Regular expressions**: Use RegExp objects for complex pattern matching
284
- - `/\.test\./` - Files containing `.test.`
285
- - `/^src\/.*\.tsx$/` - `.tsx` files directly in the `src` directory
286
-
287
- **Advanced: Lookahead/Lookbehind Support**
161
+ - **Regular expressions**: RegExp objects for complex matching
162
+ - `/\.test\./` files containing `.test.`
163
+ - `/^src\/.*\.tsx$/` `.tsx` files directly in the `src` directory
288
164
 
289
165
  The Rust regex engine fully supports lookahead and lookbehind assertions,
290
- enabling sophisticated filtering patterns:
291
- - **Negative Lookahead** `(?!...)`: Match if NOT followed by pattern
292
- - `/node_modules(?!\/@stylexjs)/` - Exclude all node_modules except
293
- @stylexjs packages
294
- - `/\.tsx(?!\.test)/` - Match .tsx files that are NOT test files
295
-
296
- - **Positive Lookahead** `(?=...)`: Match if followed by pattern
297
- - `/.*\.test(?=\.tsx$)/` - Match only .test.tsx files
298
-
299
- - **Negative Lookbehind** `(?<!...)`: Match if NOT preceded by pattern
300
- - `/(?<!src\/).*\.tsx$/` - Exclude .tsx files not in src/
301
-
302
- - **Positive Lookbehind** `(?<=...)`: Match if preceded by pattern
303
- - `/(?<=components\/).*\.tsx$/` - Match only .tsx files in components/
304
-
305
- #### Filtering Rules
166
+ which the JavaScript-side patterns can rely on:
167
+ - Negative lookahead `(?!...)`: `/node_modules(?!\/@stylexjs)/` excludes all
168
+ of `node_modules` except `@stylexjs` packages
169
+ - Positive lookahead `(?=...)`: `/.*\.test(?=\.tsx$)/` matches only
170
+ `.test.tsx` files
171
+ - Negative lookbehind `(?<!...)`: `/(?<!src\/).*\.tsx$/` excludes `.tsx` files
172
+ outside `src/`
173
+ - Positive lookbehind `(?<=...)`: `/(?<=components\/).*\.tsx$/` matches only
174
+ `.tsx` files in `components/`
175
+
176
+ ### Filtering Rules
306
177
 
307
178
  1. If `include` patterns are specified and not empty, files must match at least
308
179
  one pattern
@@ -310,18 +181,17 @@ if (shouldTransform) {
310
181
  3. Exclude patterns take precedence over include patterns
311
182
  4. All paths are matched relative to the current working directory
312
183
 
313
- #### Common Use Cases
184
+ ### Common Use Cases
314
185
 
315
- **Exclude all node_modules except specific packages:**
186
+ Exclude all of `node_modules` except one package:
316
187
 
317
188
  ```ts
318
- // Exclude all node_modules except @stylexjs/open-props
319
189
  shouldTransformFile(filePath, undefined, [
320
190
  /node_modules(?!\/@stylexjs\/open-props)/,
321
191
  ]);
322
192
  ```
323
193
 
324
- **Transform only specific packages from node_modules:**
194
+ Transform only specific packages from `node_modules`:
325
195
 
326
196
  ```ts
327
197
  shouldTransformFile(
@@ -335,22 +205,10 @@ shouldTransformFile(
335
205
  );
336
206
  ```
337
207
 
338
- **Exclude multiple node_modules packages except a few:**
339
-
340
- ```ts
341
- // Exclude all node_modules except @stylexjs packages
342
- shouldTransformFile(filePath, undefined, [/node_modules(?!\/@stylexjs)/]);
343
- ```
344
-
345
- ### SWC Plugin Support
208
+ ## SWC Plugin Support
346
209
 
347
- > [!NOTE]
348
- >**New Feature:** The compiler now supports running SWC WASM plugins
349
- > before StyleX transformation. This allows you to chain transformations and
350
- > integrate custom SWC plugins seamlessly.
351
-
352
- The `transform` function accepts an optional `swcPlugins` array in the options
353
- object, allowing you to run SWC WASM plugins before the StyleX transformation:
210
+ The `transform` function accepts an optional `swcPlugins` array, allowing you to
211
+ run SWC WASM plugins before the StyleX transformation:
354
212
 
355
213
  ```ts
356
214
  const { transform } = require('@stylexswc/rs-compiler');
@@ -380,124 +238,27 @@ const { code, metadata, map } = transform('Button.tsx', sourceCode, {
380
238
  });
381
239
  ```
382
240
 
383
- #### How It Works
241
+ How it works:
384
242
 
385
- 1. **Plugin Execution Phase**: If `swcPlugins` are provided, the source code is
243
+ 1. **Plugin execution phase**: if `swcPlugins` are provided, the source code is
386
244
  first transformed using `@swc/core`'s `transformSync` with the specified WASM
387
245
  plugins
388
- 2. **StyleX Transformation Phase**: The plugin-transformed code is then passed
246
+ 2. **StyleX transformation phase**: the plugin-transformed code is then passed
389
247
  to the StyleX compiler
390
248
 
391
- #### Plugin Configuration
392
-
393
- Each plugin in the `swcPlugins` array is a tuple of:
394
-
395
- - **Plugin Path** (string): Can be:
396
- - An absolute path to a `.wasm` file: `/path/to/plugin.wasm`
397
- - An npm package name: `@swc/plugin-emotion`
398
- - **Plugin Config** (object): Plugin-specific configuration options
399
-
400
- #### Example: Custom Theme Plugin
401
-
402
- ```ts
403
- transform(filename, code, {
404
- dev: true,
405
- swcPlugins: [
406
- [
407
- '/Users/me/plugins/swc_plugin_theme.wasm',
408
- {
409
- themeName: 'theme-name',
410
- themeConfig: {
411
- primaryColor: 'blue',
412
- spacing: 8,
413
- },
414
- },
415
- ],
416
- ],
417
- });
418
- ```
419
-
420
- #### Benefits
249
+ Each entry in `swcPlugins` is a tuple of:
421
250
 
422
- - Chain multiple transformations seamlessly
423
- - Leverage the SWC plugin ecosystem
424
- - Custom preprocessing before StyleX transformation
425
- - ✅ Full compatibility with SWC WASM plugins
426
- - ✅ No additional build configuration needed
427
-
428
- ### Output
429
-
430
- The output from the compiler includes the transformed code, metadata about the
431
- generated styles, and an optional source map.
432
-
433
- ```json
434
- {
435
- "code": "import * as stylex from '@stylexjs/stylex';\nexport const styles = {\n default: {\n backgroundColor: \"xrkmrrc\",\n color: \"xju2f9n\",\n $$css: true\n }\n};\n",
436
- "metadata": {
437
- "stylex": {
438
- "styles": [
439
- [
440
- "xrkmrrc",
441
- {
442
- "ltr": ".xrkmrrc{background-color:red}",
443
- "rtl": null
444
- },
445
- 3000
446
- ],
447
- [
448
- "xju2f9n",
449
- {
450
- "ltr": ".xju2f9n{color:blue}",
451
- "rtl": null
452
- },
453
- 3000
454
- ]
455
- ]
456
- }
457
- },
458
- "map": "{\"version\":3,\"sources\":[\"<anon>\"],\"names\":[],\"mappings\":\"AACE;AACA;;;;;;EAKG\"}"
459
- }
460
- ```
461
-
462
- ## Example
463
-
464
- Below is a simple example of input StyleX code:
465
-
466
- ```ts
467
- import * as stylex from '@stylexjs/stylex';
468
-
469
- const styles = stylex.create({
470
- root: {
471
- padding: 10,
472
- },
473
- element: {
474
- backgroundColor: 'red',
475
- },
476
- });
477
-
478
- const styleProps = stylex.props(styles.root, styles.element);
479
- ```
480
-
481
- Output code:
482
-
483
- ```ts
484
- import * as stylex from '@stylexjs/stylex';
485
- const styleProps = {
486
- className: 'x7z7khe xrkmrrc',
487
- };
488
- ```
489
-
490
- ## Compatibility
491
-
492
- > [!IMPORTANT]
493
- > The current resolution of the `exports` field from
494
- > `package. json` is only partially supported, so if you encounter problems,
495
- > please open an
496
- > [issue](https://github.com/Dwlad90/stylex-swc-plugin/issues/new) with an
497
- > attached link to reproduce the problem.
251
+ - **Plugin path** (string): an absolute path to a `.wasm` file
252
+ (`/path/to/plugin.wasm`) or an npm package name (`@swc/plugin-emotion`)
253
+ - **Plugin config** (object): plugin-specific configuration options
498
254
 
499
255
  ## Configuration Options
500
256
 
257
+ The compiler accepts the standard StyleX options (`dev`, `debug`,
258
+ `importSources`, `unstable_moduleResolution`, and so on — see the
259
+ [StyleX configuration docs](https://stylexjs.com/docs/api/configuration/babel-plugin/))
260
+ plus the compiler-specific options below.
261
+
501
262
  ### `injectStylexSideEffects`
502
263
 
503
264
  **Type:** `boolean` **Default:** `false`
@@ -505,10 +266,8 @@ const styleProps = {
505
266
  Automatically injects side-effect imports for `.stylex` and `.consts` files to
506
267
  prevent tree-shaking from removing them during bundling.
507
268
 
508
- #### Problem
509
-
510
- When using build tools that perform tree-shaking (like webpack, rollup, vite),
511
- imports from `.stylex` or `.consts` files may appear unused after StyleX
269
+ The problem: when build tools perform tree-shaking (webpack, Rollup, Vite),
270
+ imports from `.stylex` or `.consts` files may appear unused after the StyleX
512
271
  transformation and get removed:
513
272
 
514
273
  ```ts
@@ -536,13 +295,11 @@ const styles = {
536
295
  };
537
296
  ```
538
297
 
539
- The bundler may remove these "unused" imports, but they're needed for other
298
+ The bundler may remove these "unused" imports, but they are needed for other
540
299
  files to resolve the same StyleX/const references correctly.
541
300
 
542
- #### Solution
543
-
544
- When `injectStylexSideEffects: true`, the compiler automatically adds
545
- side-effect imports to preserve these modules:
301
+ With `injectStylexSideEffects: true`, the compiler adds side-effect imports to
302
+ preserve these modules:
546
303
 
547
304
  ```ts
548
305
  // After transformation with injectStylexSideEffects: true
@@ -550,116 +307,106 @@ import { colors } from './theme.stylex';
550
307
  import { spacing } from './tokens.consts';
551
308
  import './theme.stylex'; // Side-effect import (prevents tree-shaking)
552
309
  import './tokens.consts'; // Side-effect import (prevents tree-shaking)
553
-
554
- const styles = {
555
- root: {
556
- backgroundColor: 'x1a2b3c',
557
- padding: 'x4d5e6f',
558
- $$css: true,
559
- },
560
- };
561
310
  ```
562
311
 
563
- #### When to Use
312
+ When to use:
564
313
 
565
- - ✅ **Use `true`** when your bundler runs StyleX transformation **before**
566
- other optimizations (recommended)
567
- - ✅ **Use `true`** with webpack's `loaderOrder: 'first'` option
568
- - ❌ **Use `false`** when StyleX runs **after** tree-shaking (e.g., webpack's
314
+ - Use `true` when your bundler runs the StyleX transformation **before** other
315
+ optimizations (recommended), for example with webpack's `loaderOrder: 'first'`
316
+ - Use `false` when StyleX runs **after** tree-shaking (e.g. webpack's
569
317
  `loaderOrder: 'last'`)
570
318
 
571
319
  > [!TIP]
572
320
  > This option is automatically enabled when using
573
321
  > `@stylexswc/webpack-plugin` with `loaderOrder: 'first'` (the default).
574
322
 
575
- ### `useRealFileForSource`
323
+ ### `inputSourceMap`
576
324
 
577
- **Type:** `boolean` **Default:** `true`
325
+ **Type:** `string` (JSON source map) **Default:** `undefined`
578
326
 
579
- Controls whether the compiler should read source files from disk for error
580
- reporting and source map generation.
327
+ Source map for the incoming `code`, produced by earlier tooling for example a
328
+ loader chain that expands compile-time macros before the StyleX transformation
329
+ runs.
581
330
 
582
- #### Behavior
331
+ The problem: when the compiler receives code already rewritten by previous
332
+ tools, positions in that code no longer match the original authored file. Two
333
+ things degrade as a result:
583
334
 
584
- - **`true` (default)**: The compiler reads the actual source file from disk when
585
- generating error messages and source maps. This provides accurate line numbers
586
- and source context that match what you see in your editor.
335
+ - Debug source-map annotations (`$$css: "file.tsx:LINE"`, emitted with
336
+ `debug: true`) point at lines of the intermediate code
337
+ - The emitted source map resolves to the intermediate code instead of the
338
+ original file
587
339
 
588
- - **`false`**: The compiler uses the transformed AST representation for error
589
- reporting. This is useful when:
590
- - Working with in-memory transformations
591
- - Source files are not available on disk
592
- - You want faster compilation (skips file I/O)
340
+ When `inputSourceMap` is provided, the compiler:
593
341
 
594
- #### Example
342
+ 1. Resolves each style namespace to its position using the namespace key's own
343
+ span — exact, with no re-parsing — and maps it through the input map back to
344
+ the original authored file
345
+ 2. Chains the emitted source map onto the input map, so downstream tooling (e.g.
346
+ devtools) resolves positions all the way back to the original file
595
347
 
596
348
  ```ts
597
- transform(filename, code, {
598
- use_real_file_for_source: true, // Use actual source files (default)
349
+ const { code, metadata, map } = transform(filename, inputCode, {
599
350
  dev: true,
600
- // ... other options
351
+ debug: true,
352
+ // Source map produced by the previous transformation step
353
+ inputSourceMap: JSON.stringify(previousStepSourceMap),
601
354
  });
602
355
  ```
603
356
 
604
- #### Use Cases
605
-
606
- **Use `true` (recommended for development):**
607
-
608
- - Local development with files on disk
609
- - Accurate error messages with real line numbers
610
- - Better debugging experience
611
- - Source maps match your actual files
612
-
613
- **Use `false` (for special cases):**
614
-
615
- - In-memory transformations without disk access
616
- - Virtual file systems
617
- - Performance optimization when error accuracy is less critical
618
- - Build pipelines where source files are not available
357
+ This is also the fastest position-resolution path: two binary searches per
358
+ namespace instead of re-reading and re-parsing the source.
619
359
 
620
360
  > [!TIP]
621
- > Keep the default `true` value for most use cases. Only set it to
622
- > `false` if you have specific requirements for in-memory transformations or
623
- > performance-critical scenarios where file I/O is a bottleneck.
361
+ > The bundler plugins (`@stylexswc/rspack-plugin`,
362
+ > `@stylexswc/webpack-plugin`, `@stylexswc/turbopack-plugin`,
363
+ > `@stylexswc/rollup-plugin`, and `@stylexswc/unplugin` on Rollup-compatible
364
+ > hosts) forward the previous loader's / plugin's source map automatically — no
365
+ > configuration needed as long as source maps are enabled in the bundler.
624
366
 
625
- > [!WARNING]
626
- > When `useRealFileForSource` is set to `false`, error messages may
627
- > report **incorrect line numbers**. The compiler will use the transformed AST
628
- > representation instead of the original source code, which can lead to line
629
- > number mismatches. This happens because:
630
- >
631
- > - The AST may have been modified by previous transformations
632
- > - Comments and whitespace are normalized in the AST
633
- > - The structure may differ from what's in your actual source file
634
- >
635
- > For accurate error reporting and debugging, always use
636
- > `useRealFileForSource: true` (the default) during development.
367
+ An invalid map is ignored with a warning, and the compiler falls back to
368
+ locating positions in the source text as described under
369
+ [`useRealFileForSource`](#userealfileforsource).
637
370
 
638
- ## Debug
371
+ ### `useRealFileForSource`
639
372
 
640
- You can enable debug logging for the StyleX compiler using the `STYLEX_DEBUG`
641
- environment variable. This is useful for troubleshooting and understanding the
642
- internal processing of StyleX code.
373
+ **Type:** `boolean` **Default:** `true`
643
374
 
644
- ### Log Levels
375
+ Controls whether the compiler reads source files from disk for error reporting
376
+ and source map generation. Only relevant when no
377
+ [`inputSourceMap`](#inputsourcemap) is available — with an input map, debug
378
+ source-map annotations are resolved from the compiler's own parse and do not
379
+ depend on this option.
645
380
 
646
- The following log levels are available:
381
+ - **`true` (default)**: the compiler reads the actual source file from disk when
382
+ generating error messages and source maps. This provides accurate line numbers
383
+ and source context that match what you see in your editor. Style namespaces
384
+ are located **by their key**, so positions resolve correctly even when the
385
+ incoming code was already rewritten by earlier tooling (keys survive
386
+ value-level transforms such as macro expansion).
647
387
 
648
- - `error`: Only shows error messages
649
- - `warn`: Shows warnings and errors (default)
650
- - `info`: Shows informational messages, warnings, and errors
651
- - `debug`: Shows debug information and all above levels
652
- - `trace`: Shows very detailed execution information
388
+ - **`false`**: the compiler uses the transformed AST representation for error
389
+ reporting. Useful for in-memory transformations, virtual file systems, or when
390
+ skipping file I/O matters more than exact positions.
653
391
 
654
- ### Usage
392
+ > [!WARNING]
393
+ > With `useRealFileForSource: false`, error messages may report
394
+ > incorrect line numbers: the AST may have been modified by previous
395
+ > transformations, comments and whitespace are normalized, and the structure may
396
+ > differ from the file on disk. Keep the default `true` during development, and
397
+ > provide an [`inputSourceMap`](#inputsourcemap) when the incoming code was
398
+ > already transformed by earlier tooling.
655
399
 
656
- Set the environment variable before running your build command:
400
+ ## Debug Logging
401
+
402
+ Enable debug logging with the `STYLEX_DEBUG` environment variable. Available
403
+ levels: `error`, `warn` (default), `info`, `debug`, `trace`.
657
404
 
658
405
  ```bash
659
406
  # Set to debug level
660
407
  STYLEX_DEBUG=debug npm run build
661
408
 
662
- # Set to trace for most verbose output
409
+ # Set to trace for the most verbose output
663
410
  STYLEX_DEBUG=trace npm run dev
664
411
  ```
665
412
 
@@ -677,11 +424,9 @@ $env:STYLEX_DEBUG="debug"; npm run build
677
424
 
678
425
  ## Error Handling
679
426
 
680
- The compiler produces clean, structured error messages with a branded `[StyleX]`
681
- prefix, replacing Rust's default panic boilerplate with user-friendly
682
- diagnostics in both the terminal and at the NAPI boundary.
683
-
684
- ### Error Format
427
+ The compiler produces structured error messages with a branded `[StyleX]`
428
+ prefix, replacing Rust's default panic boilerplate with readable diagnostics in
429
+ both the terminal and at the NAPI boundary.
685
430
 
686
431
  All StyleX errors follow this format in the terminal:
687
432
 
@@ -699,6 +444,39 @@ Errors are color-coded for readability:
699
444
  | Unimplemented feature | `[UNIMPLEMENTED]` | Magenta label |
700
445
  | Internal unreachable state | `[UNREACHABLE]` | Blue label |
701
446
 
447
+ ## FAQ
448
+
449
+ ### Is this a drop-in replacement for `@stylexjs/babel-plugin`?
450
+
451
+ Yes, by design. It implements the same transform, is validated against the
452
+ official StyleX test suite, and produces compatible output. It also adds
453
+ compiler-only capabilities: `include`/`exclude` filtering, SWC WASM plugin
454
+ chaining, `inputSourceMap` chaining, and structured metadata output.
455
+
456
+ ### Do I need Rust installed to use it?
457
+
458
+ No. Prebuilt native binaries are published for each supported platform and
459
+ installed automatically as optional dependencies.
460
+
461
+ ### Which package should I install for my app?
462
+
463
+ One of the bundler integrations listed at the top of this page. Install
464
+ `@stylexswc/rs-compiler` directly only when building custom tooling on top of
465
+ the `transform` API.
466
+
467
+ ### Known limitations?
468
+
469
+ Resolution of the `exports` field in `package.json` is only partially supported.
470
+ If you hit a problem, please open an
471
+ [issue](https://github.com/Dwlad90/stylex-swc-plugin/issues/new) with a
472
+ reproduction link.
473
+
474
+ ## Documentation
475
+
476
+ - [StyleX documentation](https://stylexjs.com)
477
+ - [NAPI-RS documentation](https://napi.rs)
478
+ - [SWC documentation](https://swc.rs)
479
+
702
480
  ## License
703
481
 
704
482
  MIT — see