Typoser
A framework-agnostic typographic style library: 10 named styles, zero runtime dependencies.
| DOMAIN | Design Systems |
| TYPE | Open-source library (npm) |
| PACKAGE | npmjs.com/package/typoser |
| SOURCE | github.com/serkansabriali/typoser |
| STACK | CSS custom properties + TypeScript token mirror |
| TYPEFACE | Open Sauce One (OFL 1.1) |
| LICENSE | MIT |
Typoser is a typographic style library that ships 10 named text styles (from display down to caption) as plain CSS custom properties with a matching TypeScript token mirror. It has zero runtime dependencies and needs no build step on the consumer side: import the stylesheet, apply a class like typo-heading-48, and the type is set. A typo-prose scope styles bare HTML from a CMS or markdown renderer with no per-element classes.
Its scope is deliberately narrow. Typoser governs type only: family, size, weight, line height, and tracking. Color, spacing, and layout are intentionally out of scope, so it drops into an existing system rather than competing with it. The whole library is a study in restraint: a small, opinionated surface that's hard to misuse.
A type system can either expose primitives (sizes, weights, spacing scales) for teams to compose freely, or ship a fixed set of finished styles. Flexibility invites drift; rigidity invites workarounds. Which constraint do you build in?
Expose the primitives as the public API. Maximum flexibility, but every team assembles its own styles, so the system fragments into one-off combinations and stops being a system.
Ship only finished named styles and hide the primitives. Less freedom, but the API stays small, consistent, and self-documenting.
The 10 named styles are the complete design API; the --typo-* custom properties exist only as integration plumbing, not a composition layer. If a needed style isn't in the set, that's a signal to propose a new named style, not to hand-roll one. Restraint is the feature.
A few choices in the scale look like mistakes and aren't. Weight progression is non-monotonic: H2, H3, and H4 all sit at Regular, with hierarchy carried by size and line height instead. Labels are sentence case, never uppercase; Semibold 600 does the emphasising. And <strong> resolves to ExtraBold 800 because 600 and 700 weren't distinct enough against the Regular and Medium bases at screen sizes. Each is a documented decision, not a default.