setwell
Typesetting for HTML. One pass over your markup gets the characters right — curly quotes, proper dashes, true minus signs — and keeps lines from breaking in the wrong places, with a few small spans for what only CSS can finish: hanging punctuation and small caps.
"Typography exists to honor content," wrote Robert Bringhurst -- and the web has rarely honored it. Browsers don't know that "quotes" curl, that 10 kg shouldn't break across a line, or that NASA looks too loud in full capitals. It's the 1990's all over again... on pp. 10-24 of the 1st draft.
“Typography exists to honor content,” wrote Robert Bringhurst—and the web has rarely honored it. Browsers don’t know that “quotes” curl, that 10 kg shouldn’t break across a line, or that NASA looks too loud in full capitals. It’s the 1990’s all over again… on pp. 10–24 of the 1st draft.
What it does
Every rule is on by default; turn off any rule, or a whole group, by name.
Quotes
Straight quotes become curly ones, paired across inline tags, with apostrophes and primes told apart.
"She said 'don't' -- twice," he wrote. He's 5'10".
“She said ‘don’t’—twice,” he wrote. He’s 5′10″.
Dashes & punctuation
Dashes for what they mean, ellipses, symbols, and stray spaces.
Open Mon-Fri, pages 10-20... (c) 2026 Acme(tm).
Open Mon–Fri, pages 10–20… © 2026 Acme™.
Numbers
The right characters for numbers, and ordinals ready for superscript.
A 1920x1080 screen at -5 °C, 1/2 full, on the 21st.
A 1920×1080 screen at −5 °C, ½ full, on the 21st.
Line breaks
Non-breaking spaces and break points, so lines end in sensible places.
On the night of the storm, Dr. Smith measured gusts of 120 km/h and stayed up until 3 am.
On the night of the storm, Dr. Smith measured gusts of 120 km/h and stayed up until 3 am.
no-break space — lines never break there.
Hyphenation
Soft hyphens in long words, invisible until a line breaks there.
An extraordinarily comprehensive, unbelievably particular approach.
An extraordinarily comprehensive, unbelievably particular approach.
Spans for CSS
Small spans that setwell.css styles: things only CSS can finish.
"NASA and the BBC," she said, "tested HTML5."
“NASA and the BBC,” she said, “tested HTML5.”
Use it
On the server, or at build time, with a string:
import { setwell } from "setwell";
import "setwell/setwell.css";
const html = setwell('<p>"Hello," she said -- it\'s NASA.</p>');In the browser, on an element already on the page:
import { setwellElement } from "setwell/dom";
await setwellElement(document.querySelector("article"));Tags, attributes and comments come out exactly as they went in; only text changes. Code, pre and anything you choose to ignore are left alone, and running it twice changes nothing the second time.
setwell is heavily inspired by typeset by David Merfield.