Serkan Sabri Ali
Product Designer
LAB—001
← Work
LAB—001

Typoser

CLIENTPersonal / open sourcePERIOD2026ROLEDesigner & Developer

A framework-agnostic typographic style library: 10 named styles, zero runtime dependencies.

DOMAINDesign Systems
TYPEOpen-source library (npm)
PACKAGEnpmjs.com/package/typoser
SOURCEgithub.com/serkansabriali/typoser
STACKCSS custom properties + TypeScript token mirror
TYPEFACEOpen Sauce One (OFL 1.1)
LICENSEMIT

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?

OPTION A

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.

OPTION B

Ship only finished named styles and hide the primitives. Less freedom, but the API stays small, consistent, and self-documenting.

CHOSEN APPROACH

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.

FIG 01 · The complete set: 10 named styles, the entire public API
PROSE SCOPE
EMPHASIS
FIG 02 · typo-prose styles unclassed CMS output; <strong> renders at ExtraBold 800 by design

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.