hraness
Theme
Appearance

stylex: one typed design system across every site

compile-time css with the portfolio palette

by hraness · drafted with ai assistance

the rest of this lesson is free: add your email to keep reading.

Keeping a dozen sites on one palette, one type scale, and one spacing system is a correctness problem as much as a design one, and the Hraness sites handle it with a type checker. They style pages with StyleX compositions: typed style declarations whose props the compiler checks, built from a shared kit. A misspelled class string is invisible until someone looks at the page. A misspelled prop fails the build.

why style drift goes unnoticed

Styling drift makes no noise. text-gray-700 in one repository and text-slate-700 in another look close enough that nobody compares them, and a hardcoded hex in a third looks right until the palette changes. Tests miss these differences because a class string promises nothing a test can hold it to.

Style decisions are also code decisions. A missing contrast pair is an accessibility bug, a missing min-width: 0 is a layout bug, and a hardcoded font stack is a brand bug. Making styles something the compiler can check turns some of those bugs into build failures.

what typed styles catch

StyleX compiles typed style declarations to atomic CSS. That has three consequences for correctness.

Style props have types. A composition declares the properties it accepts, and a call site that passes an unknown prop or a value of the wrong type fails to compile. “The footer accepts a tone and a compact flag” is an interface the compiler enforces rather than a line in a doc.

Values come from one place. The palette and type scale live in @hraness/ui and @hraness/design-kit as constants, and sites compose from them instead of restating them. The muted text color is the same token on every site, so a palette change is one edit instead of a search across a dozen repositories.

The output is deterministic. The CSS is generated at build time from the same declarations, so the shipped stylesheet follows from the source and a test can assert on it. aicharts' CSS contract test does this, checking the compiled output against the declared design rules.

recipes and pinned stylesheets

The sites do not write ad hoc CSS. They build pages from named recipes (rows, panes, controls, prose widths), and each product supplies its own category colors through tokens. The product decides what it wants to look like, the kit decides how that renders, and the types keep the two in step.

Each site also bundles the released kit stylesheets with their licenses, and a checked-in file records the SHA-256 of every bundled file. The visual output is then a build artifact a test can hash, where a stylesheet loaded from a CDN could change underneath the site.

what the compiler cannot see

Types check the shape of a style call, not whether the result looks right. tone="subtle" compiles whether or not subtle is the right choice for that element. Contrast, layout, and overflow are visual properties, and they need the browser checks from the Direct lesson. StyleX catches misuse of the API; it does not catch a poor design decision.

The compiler also sees only what passes through it. A dangerouslySetInnerHTML blob, an inline SVG with its own fills, or an iframe of outside content never touches the typed styles. The sites keep those exceptions visible in the code, as bundled assets, content-addressed media, and hash-pinned files, so nobody mistakes them for checked styles.

The shared kit is a dependency like any other. Each site pins a released version, and a kit upgrade is a reviewed change in each site rather than one coordinated bump across all of them. At any moment, then, the sites share a vocabulary and may still render slightly differently until each one upgrades.

keep reading: free for subscribers

the rest of this lesson is free. enter your email to subscribe, and every subscriber lesson unlocks in this browser.

already subscribed? enter the same email to unlock.