Zero dependencies · One file · MIT
A component library where every surface is printed, not painted. Buttons, charts, switches and washes are halftone screens pressed onto canvas — the way ink actually lands on paper.
Every fill below is a live canvas: a seeded dot cloud, thresholded against a tone field. Same engine as the charts, the mascot, and the wash behind a sign-up card.
A halftone screen fakes continuous tone with discrete marks. Change the screen and the whole page changes character — the tone field underneath never moves.
One idea, applied to everything: threshold a tone field against a screen. That single operation is what halftone means, and it's the whole library.
// every component is a tone function 0..1 const meter = surface(canvas, { // how dark is the ink at this point? tone: (p, W, H) => p.x / W < 0.72 ? 0.95 : 0.05, pattern: "hatch", }) // the press: keep the dots whose // threshold the local tone can reach for (const p of dots) { if (tone(p) > p.threshold) ink(p) }
The dots come from a seeded Poisson-disk cloud — blue noise, which is exactly what stochastic screening uses on a real press. Each point carries its own threshold, so a point only takes ink where the tone is dark enough to reach it.
Because the seed is deterministic, a reload gives you the same ten thousand dots. Reroll and the whole page reprints at once.
Animation never tweens CSS. A value glides, every dot re-tests its threshold, and the grain itself is the motion.
A full docs site in one self-contained HTML file — no build step, no CDN, works straight from file://.
Primitives (switch, slider, OTP field, dialogs, menus, combobox), charts (line, pie, radar, area, bars, heatmap, donut), whole page examples (dashboard, pricing, billing, sign-in flows), real light & dark themes, an OKLCH hue wheel that rotates every pigment on the page, and Smudge — the resident ink imp, pressed from the same engine.
There's nothing to install. It's one HTML file.
# clone it git clone https://github.com/ecgang/halftone-ui.git open halftone-ui/docs/index.html # or just download docs/index.html and double-click it — # engine, docs, demos and themes are all inside.
Packaged @halftone-ui/core, /vue and /react builds are on the roadmap; the single-file demo is the source of truth for the engine today.