Frontend Development 11 min read

Introducing broken-css: A Zero‑Runtime Atomic CSS‑in‑JS Solution

The article explains broken-css, a zero‑runtime, atomic CSS‑in‑JS library inspired by linaria and stylex, detailing its design, installation, API, compilation process, support for pseudo‑classes, @‑rules, CSS variables, and integration with webpack and VSCode, while also providing code examples and performance benefits.

ByteDance ADFE Team
ByteDance ADFE Team
ByteDance ADFE Team
Introducing broken-css: A Zero‑Runtime Atomic CSS‑in‑JS Solution

Technical background : Modern UI frameworks increasingly accept JSS, and solutions such as linaria and stylex demonstrate the trend toward zero‑runtime, compile‑time CSS extraction.

linaria is an open‑source, zero‑runtime JSS tool that extracts styles at build time, allowing browsers to download CSS and JSS in parallel for better performance and bundle size.

stylex is Facebook's internal, closed‑source atomic JSS solution that also compiles JSS to atomic CSS at build time, maximizing reuse.

const styles = stylex.create({
  blue: {color: 'blue'},
  red: {color: 'red'}
});
function MyComponent(props) {
  return (
I'm blue
);
}

The above is compiled to:

.c0 { color: blue }
.c1 { color: red }

broken-css draws inspiration from linaria and stylex but offers a zero‑runtime, atomic JSS approach using a template‑string API, making it easy to support animations, pseudo‑classes, and traditional usage patterns.

Installation : Run yarn add @broken-css/core and yarn add -D @broken-css/webpack-loader .

@broken-css/core provides a css tag function that throws an error if executed at runtime, ensuring the code is only transformed during compilation.

export const css = (_literal: TemplateStringsArray, ..._DOES_NOT_SUPPORT_EXPRESSIONS: never[]): string => {
  throw new SyntaxError('Do not call css() on runtime!');
};

@broken-css/webpack-loader replaces JSS calls with atomic class names and injects the generated CSS into the bundle, delegating import handling to webpack.

Example : Two components, Foo and Bar , use the css template literal to define styles, including keyframes, hover effects, and pseudo‑elements.

// Foo.tsx
import { css } from "@broken-css/core";
import React, { FC } from "react";

const Foo: FC = () => {
  return (
foo
);
};
export default Foo;

// Bar.tsx
import { css } from "@broken-css/core";
import React, { FC } from "react";

const Bar: FC = () => {
  return (
bar
);
};
export default Bar;

After compilation, the components receive hashed class names (e.g., _0e91 _b38a _43fe _b04b _4b6c ) and the generated CSS is emitted to broken.css :

/** broken.css **/
@keyframes shake { ... }
._0e91:hover { animation: shake 0.82s ...; }
._b38a::after { content: ' after'; color: brown; }
._43fe { color: red; }
._b04b { font-size: 24px; }
._4b6c { border: 1px solid black; }
._f617 { border: 1px black solid; }

Atomicization : broken-css hashes each style rule to generate a unique class name; identical rules across files produce the same hash, enabling deduplication and reuse. However, syntactically different but visually identical rules (e.g., different border order) are not merged.

Size advantage : Initially the CSS bundle size may not shrink, but as the project grows and duplicate styles accumulate, the atomic approach reduces overall size, turning a linear growth curve into a sub‑linear one.

Pseudo‑class support : Rules like &:hover are transformed by replacing & with the generated hash, allowing fine‑grained reuse.

// a.js
const cls1 = css`
  color: red;
`;

// b.js
const cls2 = css`
  &:hover {
    color: red;
    font-size: 24px;
  }
`;

Compiled output:

// a.js
const cls1 = 'c1';
/*
  color: red;
*/

// b.js
const cls2 = 'c2 c3';
/*
  &:hover {
    color: red;
    font-size: 24px;
  }
*/
.c1, .c2:hover { color: red; }
.c3:hover { font-size: 24px; }

@‑rule support : @‑rules such as keyframes and media queries are passed through unchanged, simply being emitted to the final CSS file. Naming isolation for @‑rules is non‑trivial because it would require global state tracking.

CSS variable handling : Variables are treated like normal declarations; they are hashed and assigned a class name.

const cls1 = css`
  --main-color: red;
  background-color: var(--main-color);
`;

const cls2 = css`
  background-color: var(--main-color);
`;

Compiled output:

const cls1 = 'c1 c2';
const cls2 = 'c2';
.c1 { --main-color: red; }
.c2 { background-color: var(--main-color); }

Tooling integration : The API works with the VSCode styled-components extension for intelligent syntax hints, and developers can optionally add stylelint-webpack-plugin for linting during the build.

Recruitment notice : The author’s ByteDance e‑commerce front‑end team is hiring interns, junior, and senior front‑end engineers; contact details are provided.

frontendCSS-in-JSWebpackAtomic CSSStylexLinariaZero-runtime
ByteDance ADFE Team
Written by

ByteDance ADFE Team

Official account of ByteDance Advertising Frontend Team

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.