Halftone UI

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.

1.00
1.00
1.2
drag it — you're running the press

Nothing here is a CSS background

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.

Press me
Button
Meter
Sparkline
Tonal orb

Four screens, one engine

A halftone screen fakes continuous tone with discrete marks. Change the screen and the whole page changes character — the tone field underneath never moves.

How it works

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.

What's in the box

A full docs site in one self-contained HTML file — no build step, no CDN, works straight from file://.

88
Sections
0
Dependencies
1
File
4
Screens
MIT
License

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.

Quick start

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.