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.

Before

"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.

After

“Typography exists to honor con­tent,” wrote Robert Bringhurst⁠—and the web has rarely hon­ored 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 cap­i­tals. 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.

Before

"She said 'don't' -- twice," he wrote. He's 5'10".

After

“She said ‘don’t’⁠—twice,” he wrote. He’s 5′10″.

Dashes & punctuation

Dashes for what they mean, ellipses, symbols, and stray spaces.

Before

Open Mon-Fri, pages 10-20... (c) 2026 Acme(tm).

After

Open Mon–⁠Fri, pages 10–⁠20… © 2026 Acme™.

Numbers

The right characters for numbers, and ordinals ready for superscript.

Before

A 1920x1080 screen at -5 °C, 1/2 full, on the 21st.

After

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.

Before

On the night of the storm, Dr. Smith measured gusts of 120 km/h and stayed up until 3 am.

After

On the night of the storm, Dr. Smith mea­sured 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.

Before

An extraordinarily comprehensive, unbelievably particular approach.

After

An extra­or­di­nar­ily com­pre­hen­sive, unbe­liev­ably par­tic­u­lar approach.

Spans for CSS

Small spans that setwell.css styles: things only CSS can finish.

Before

"NASA and the BBC," she said, "tested HTML5."

After

“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.