Sass mixins have been the duct tape holding design systems together for over a decade. That era is winding down. The CSS Working Group has shipped the @mixin and @apply spec, Chromium has an early prototype behind a flag, and Interop 2026 lists native mixins as a focus area — meaning Firefox and Safari are committed to shipping compatible implementations.
For design system teams, this isn't just "Sass but native." It rewrites the contract between your token layer and your consumers.
What @mixin and @apply actually look like
If you've written Sass, the syntax will feel immediately familiar — and that's intentional. The spec authors wanted migration to be a matter of search-and-replace, not a rewrite.
@mixin --stack(--gap: 1rem) {
display: flex;
flex-direction: column;
gap: var(--gap);
}
.sidebar {
@apply --stack;
}
.card-list {
@apply --stack(--gap: 2rem);
}
The double-dash prefix (--stack) follows the same convention as custom properties. Parameters use the same --name: default pattern. No new naming scheme to learn, no special compiler to configure — just CSS.
One key difference from Sass: native mixins don't duplicate declarations in the output. Sass compiles a mixin into each selector that includes it, bloating your stylesheet. The browser, by contrast, resolves @apply at render time. Ten components using --stack don't produce ten copies of those three declarations. They reference one definition.
Why this matters more than "fewer devDependencies"
Dropping Sass from your build pipeline is the obvious win, sure. But the deeper shift is about who can consume your design system.
Right now, if your tokens ship as Sass variables and mixins, you're making a technology choice for every consumer. A React team using CSS Modules can probably integrate. A team on Web Components with plain CSS? They need a build step they didn't ask for, or they manually copy your token values into their own variables — and now you have drift.
Native mixins change this calculus. Your design system publishes a CSS file. Any project that can load a stylesheet — framework, no framework, server-rendered, static HTML — gets the full mixin library. No transpiler. No plugin configuration. No version conflicts between sass and sass-embedded.
That's a genuine architectural simplification, not a cosmetic one.
The design token connection
Here's where it gets interesting for teams already invested in the W3C Design Token Community Group format. Today the pipeline typically looks like:
Figma → tokens JSON → Style Dictionary → Sass variables + CSS custom properties
With native mixins, you can collapse the tail end of that chain. Style Dictionary (or your tool of choice) outputs a single CSS file that contains both your custom properties and your mixins. The properties carry your primitive and semantic values. The mixins encode your compositional patterns — your spacing stacks, your typography scales, your elevation recipes.
/* tokens.css — generated from your token pipeline */
:root {
--color-surface: #fff;
--color-border: #e2e2e2;
--radius-md: 8px;
--shadow-sm: 0 1px 3px rgba(0,0,0,.08);
}
@mixin --card-surface {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
box-shadow: var(--shadow-sm);
}
One file. No intermediate formats. Consumers @import it and @apply --card-surface wherever they need it. Theme switching still works because the mixin references custom properties, not hard-coded values — swap the properties at a scope boundary and the mixin output follows.
What about Tailwind v4?
Tailwind v4 already moved to a CSS-first configuration where all tokens are native custom properties. Its utility classes are essentially pre-built "apply this set of properties" shortcuts. Native mixins don't replace Tailwind — but they do overlap with one of its core value propositions: sharing compositional styles without writing a component.
The difference is granularity. Tailwind gives you atomic utilities you compose in HTML. Mixins let you compose in CSS, bundling several declarations under a semantic name. For design system authors, mixins are the more natural primitive. You don't want consumers choosing between gap-4 and gap-6 — you want them applying --stack and getting the system-blessed default.
Both can coexist. But if your team has been using @apply in Tailwind (the directive, not the CSS spec) to avoid long class strings, native @apply is the spec-backed version of exactly that pattern.
The migration question nobody's asking yet
Most design system teams are planning their Sass-to-native migration as a future quarter's initiative. Here's the uncomfortable question: do you even need to migrate, or do you just stop adding new Sass?
A pragmatic approach:
New tokens and mixins ship as native CSS
Existing Sass mixins continue to work (Sass isn't going anywhere as a tool)
When a component gets its next major refactor, it moves to native
Eventually the Sass dependency becomes vestigial and you drop it
No big-bang rewrite. No migration sprint. Just a gradual shift in where new patterns land.
Rough edges to watch
It's early. The spec is solid but implementations are still behind flags. A few things to keep your eye on:
@contentsblocks — the spec includes a way for mixins to accept blocks of declarations from the call site, like Sass's@content. Browser support for this part is trailing behind the basic@mixin/@applypair.Specificity — applied declarations inherit the specificity of the rule they land in, not the mixin definition. This is correct behavior but will surprise teams used to Sass's flat output.
Tooling gaps — VS Code intellisense, Stylelint rules, and Figma-to-CSS plugins haven't caught up yet. Expect six months of rough developer experience before the ecosystem fills in.
None of these are blockers for experimentation. They're blockers for shipping to production at scale — which, given Interop 2026's timeline, puts real cross-browser support somewhere in late Q3 or Q4.
So what do you do today?
Start writing your next design system primitive as a native mixin behind a feature flag or in a /experimental directory. Pick something small — a typography scale mixin, a focus-ring recipe, a responsive container pattern. Get the authoring feel. See how it plays with your existing token pipeline.
The build step isn't dead yet. But it just got a lot harder to justify for the styling layer alone.