Repository navigation
feat(stylex): add native StyleX compiler and pass - #127
Open
MarcelOlsen wants to merge 5 commits into
Open
MarcelOlsen wants to merge 5 commits into
MarcelOlsen wants to merge 5 commits into
Conversation
MarcelOlsen
force-pushed
the
stylex
branch
4 times, most recently
from
August 31, 2026 16:42
b1e5b5e to
27f75b5
Compare
Clean-room Rust compiler for StyleX, byte-identical to @stylexjs/babel-plugin 0.19.0: identical rule metadata, identical generated JavaScript, identical assembled CSS, or a hard error. Parity is enforced by a differential harness (live Babel plugin as oracle, 5,325 job-modes, 0 FAIL, in CI) living with the compiler's source of truth; this copy is vendored from there (lovable@2ccd45e9ac6) and is not edited in place. Unsupported features hard-error rather than diverge (runtimeInjection: true, haste, legacy option modes, Flow-only syntax). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lre78sAtefzg8D2PJVpNxa
Dev pipeline: a pre-Transformer AST pass on gated modules (path globs + SIMD content scan; one parse per module, synthesized nodes carry replaced-node spans so sourcemaps stay valid), rules persisted on CachedModule and replayed on cache hits so warm starts rebuild the registry, @stylex; directive substitution into served css, css-update repush on gated-module changes, /@oj/stylex.css debug route. Build: a rolldown transform plugin (string seam with a real splice sourcemap); the directive rides sidecar phases as an unknown at-rule sentinel and the assembled sheet splices in before emit_split_css. Enabled by a stylex config section (--stylex-config / OJ_STYLEX_CONFIG override), or automatically when package.json depends on @stylexjs/stylex. Substituted sheets parse with lightningcss error_recovery: upstream emits @position-try rules browsers skip and the compiler reproduces upstream byte-for-byte. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lre78sAtefzg8D2PJVpNxa
Compiler-only update of the vendored crate (perf waves 1 and 2 on the source of truth), byte-identical to the previous copy on every corpus of the conformance harness: both output backends over the synthetic, community and real-app corpora incl. dev modes, style-free files, four assemble feeds and `compile`. Measured against the previous vendored copy (interleaved fresh processes, min of 7): astryx -37% instructions retired, the real app in dev mode -31%, the AST backend oj's dev path uses -19%, and the one-shot assembler on a 72k-rule registry feed 45ms -> 5ms with peak RSS 88MB -> 42MB. No call-site changes: the pass and the registry use the crate exactly as before. Three seam test literals follow the crate's data model (`StylexRule` text fields are `Arc<str>`, `const_val` is boxed); no production code in the seams changes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019zUixZf3Yr7Rti83WUkyRW
Compiler-only update of the vendored crate (perf wave 3 on the source of truth): a prefetching reader for path jobs, walk fusion in the transform, and a flagged native scope-analysis spike that stays off by default. The compiler now depends on oxc_str directly, pinned to the workspace oxc line. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q8a3Twu8KWSQpkJbXPjwwW
Sync the compiler allocation reductions and adaptive prepared-rule storage from the source of truth. Preserve the OJ workspace manifest and existing integration call sites.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds native StyleX support to OJ's development and build pipelines, using the clean-room Rust compiler
fruvendored atcrates/stylex. The current compiler source is synced fromlovable@d61e617fb93d174d892bbffb0dc83e2290c39508; the OJ workspace manifest remains adapted for this repository. Babel 0.19.0 is the compatibility oracle.Development transforms OJ's parsed AST before lowering. Compiled rules travel with cached modules, populate the stylesheet registry, replace
@stylex;in served CSS, and trigger CSS updates when gated modules change. The build pipeline uses a Rolldown string transform with a splice source map, then assembles and inserts the stylesheet after bundling. The pass auto-enables when the app depends on@stylexjs/stylex; thestylexconfig section,--stylex-config, orOJ_STYLEX_CONFIGsupplies explicit settings.{ "stylex": { "include": ["src/**"], "useCssLayers": true, "dev": true } }The latest compiler sync reduces temporary allocations by iterating simple evaluated namespaces directly and representing ordinary single-property paths implicitly. Complex styles retain the existing validation and flattening pipeline. The library's
RuleRegistryalso shares prepared rules when repetition warrants it, returns to inline storage when repetition disappears, and avoids duplicate preparation on first emission. OJ currently calls the one-shot assembler, so those registry savings require a later integration change. The standalone CLI queue change is outside this vendored library.Compiler measurements on a 3,103-module corpus, Apple M5 Max, Rust 1.95.0, one worker:
create()Total compiler instructions fell about 3%. The allocated-byte reduction is temporary allocation traffic; peak heap stayed unchanged. Stage timing and allocation counting used separate runs. Whole-OJ experiments using a separate AST-hook prototype found 0.7–1.5% fewer instructions with PGO, but no consistent wall-time improvement. Those are prototype measurements, not a claimed speedup for this PR's string build integration. The AST-hook adapter and whole-OJ PGO setup are separate work; native scope analysis remains opt-in through
FRU_NATIVE_SCOPES=1.The retained compiler snapshot produced byte-identical complete outputs before and after the optimizations across four corpora at one and eight workers and passed 5,325 live Babel comparisons in its source repository. That repository keeps the full conformance harness and integration fixtures. Tests in this sync pin numeric property order, the
$$cssinsertion position, dynamic class paths, error ordering, and the registry's transition from repeated to unique rules.Two known integration constraints remain:
@position-tryoutput is reproduced for compatibility. StyleX-substituted sheets therefore use Lightning CSS error recovery; other sheets remain strict.