Skip to content

WIP add @compiled/vanilla#1885

Open
xtan-atlas wants to merge 2 commits into
masterfrom
xtan/compiled-vanilla
Open

WIP add @compiled/vanilla#1885
xtan-atlas wants to merge 2 commits into
masterfrom
xtan/compiled-vanilla

Conversation

@xtan-atlas
Copy link
Copy Markdown

@xtan-atlas xtan-atlas commented Apr 22, 2026

What is this change?

Adds a new @compiled/vanilla package exposing cssMap and ax for use in non-React code. Wires up the Babel plugin and babel-plugin-strip-runtime to recognise @compiled/vanilla imports and emit framework-agnostic output: an insertSheets([...]) call replaces the <CC><CS> JSX wrapper, no React or forwardRef import is added, and production extraction routes the rules into the existing .compiled.css pipeline.

Why are we making this change?

The Editor migration from Emotion to Compiled needs a path for non-React code (e.g. ProseMirror toDOM helpers). Without it, those files stay on Emotion and Editor ships two CSS-in-JS runtimes, defeating most of the bundle-size win from the React-side migration.

How are we making this change?

The CSS pipeline (buildCss, transformCssItems, atomicifier, sorter, hasher) is unchanged — vanilla calls the same functions and gets back the same (sheets, classNames) data. Only the code-emission layer is new, gated by state.isVanilla set when the plugin sees an @compiled/vanilla import. insertRule is promoted to a public @compiled/react/runtime export so vanilla and React rules cohabit the same <style> buckets in document.head.

The internal insertSheets call is removed when extract css into .compiled.css via babel-plugin-strip-runtime.

Out of scope

  • Smart atomisation heuristic

PR checklist

Don't delete me!

I have...

  • Updated or added applicable tests
  • Updated the documentation in website/
  • Added a changeset (if making any changes that affect Compiled's behaviour)

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 22, 2026

🦋 Changeset detected

Latest commit: c27f14f

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

This PR includes changesets to release 18 packages
Name Type
@compiled/vanilla Minor
@compiled/babel-plugin Minor
@compiled/babel-plugin-strip-runtime Minor
@compiled/utils Minor
@compiled/react Minor
@compiled/parcel-transformer Patch
@compiled/vite-plugin Patch
@compiled/webpack-loader Patch
@compiled/codemods Patch
@compiled/css Patch
@compiled/eslint-plugin Patch
@compiled/parcel-optimizer Patch
@compiled/parcel-optimizer-test-app Patch
@compiled/parcel-transformer-test-app Patch
@compiled/parcel-transformer-test-compress-class-name-app Patch
@compiled/parcel-transformer-test-custom-resolve-app Patch
@compiled/parcel-transformer-test-custom-resolver-app Patch
@compiled/parcel-transformer-test-extract-app Patch

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

@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 22, 2026

Deploy Preview for compiled-css-in-js canceled.

Name Link
🔨 Latest commit c27f14f
🔍 Latest deploy log https://app.netlify.com/projects/compiled-css-in-js/deploys/69e86085c3d10f00082269ce

Copy link
Copy Markdown
Collaborator

@kylorhall-atlassian kylorhall-atlassian left a comment

Choose a reason for hiding this comment

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

Honestly, this leaves me pretty surprised and happy with what I see so far. I'd have to give these things a dry-run, I don't quite feel there's enough test coverage, eg. we have more end-to-end and performance tests with React that are manually spin up, not put into CI, that are worth either creating or trying to run.

But this is enough to test and validate if it's even close before shipping a 0.x and calling it a pre-release — to that effect, happy to not document it on the web, or mark it as an Alpha early release in both README and web.

Comment on lines +17 to +22
// Result is a plain className-string map; no JSX wrapper.
expect(actual).toInclude('base:');
expect(actual).toInclude('accent:');
// Sheets are inserted via the vanilla runtime, not the React runtime.
expect(actual).toInclude('import { ax, insertSheets } from "@compiled/vanilla/runtime"');
expect(actual).toInclude('insertSheets(');
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'd expect at least one full snapshot on one of these, I think it's fair to add if it's deterministic.

Comment on lines +24 to +27
// `CS` is needed. `ix` is omitted because vanilla `cssMap` does not support
// dynamic CSS variable interpolation today (the runtime helper for that lives
// in `@compiled/react/runtime` and is JSX-shaped). When dynamic interpolation
// is added to vanilla, `ix` should be re-introduced here.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Ah, I'd say that's quite important, but shouldn't block a demo.

Just ensure the TS API or something blows up if used, otherwise it could be really confusing…

// sheets are inserted via `insertSheets` from
// `@compiled/vanilla/runtime`, no React or `forwardRef` import is
// added, and no `<CC><CS>` wrapper is generated.
if (userLandModule === COMPILED_VANILLA_IMPORT) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Question, could we have @compiled/react and @compiled/vanilla in the same file?

Would these sorts of things fail here with this state, or what level is this state? I feel like it's at a file level.

So we do a pass, hit a cssMap from vanilla and then hit a styled from react and do what?

I'd suggest a file init health-check if not already somewhere to just fast fail if both imports are found in the same file (by both I mean (@compiled/react or @atlaskit/css) and @compiled/vanilla)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Could use some web documentation, but honestly looking real great. Feeling the vibes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants