config.json.
Hack is bundled
The default font ships inside the binary. It renders identically on every machine without relying on a system install, so a fresh laptop looks like the one you set up last year.Fallbacks
font_family is the primary face; font_fallbacks is an ordered list tried in
turn for anything the primary lacks.
font_fallbacks out and you get the platform’s default chain:
Each ends in faces the host OS actually ships, and those stock names are
appended to whatever list you write yourself — so a
config.json copied from
another platform still resolves.
OpenType features
font_features passes tags straight through to the shaper:
true/false map to 1/0.
Anything malformed is skipped with a log line rather than failing the whole
config.
Writing any tag hands the whole feature set to you: the terminal only names
calt: 0, liga: 0 and clig: 0 itself while font_features is unset. So
{"font_features": {"zero": 1}} turns slashed zeroes on and ligatures back
on. Name them explicitly if you want both:
Stroke weight on macOS
macOS font smoothing thickens glyph strokes, and by how much depends on the text colour: the lighter the text, the bolder it draws. That is why light text on a dark theme can look heavier in tty7 than in a terminal that turns the effect off, and why a thinner weight of the same family does not fully make up for it. Settings → Appearance → Terminal text → Thicken strokes (font_thicken)
turns it off, so glyphs draw at the face’s own weight whatever their colour:
The change applies the next time tty7 starts: the preference is read once,
when text is first drawn. It covers tty7 alone — no other app, and not the
system-wide setting.
defaults write com.github.tty7 AppleFontSmoothing -int 0 keeps working. This
is the same switch as Ghostty’s font-thicken and iTerm2’s thin strokes, with
tty7 defaulting to the macOS look. Windows and Linux do not thicken strokes, so
the key does nothing there.
CJK and the two-column grid
A cell is one advance of the primary face, and a wide (CJK) character is
pinned to exactly two of them. A CJK fallback sits flush in its slot only if
its ideographs advance twice the primary’s Latin advance.