Free · no sign-up · never leaves your browser
Cursed Font Generator
Make a cursed font in the browser. Type a sample, pick a distortion, drag the intensity — then download a real .ttf you can install in any app.
Set the damage
outline displacement · units per em 1000
5 · cursed
Intensity 9–10 can push outlines past self-intersection, which makes hairline spikes. 7 is usually the sweet spot for usable-but-ugly.
Live specimen
Your specimen appears here — start typing.
style Wobble · intensity 5 · upem 1000
The .ttf always ships the full Latin-1 glyph set, whatever you type here.
Forging the full Latin-1 outline set… the preview is already live.
How it works
Four steps, all of them inside this tab.
Each Latin-1 glyph of your system serif is rasterised to a canvas and its outline traced with marching squares — every counter and serif preserved as polygons.
The chosen recipe displaces every on-curve point: shear matrices, sine warps, gravity sag, seeded per-point noise, x-height squash or per-glyph rotation.
A TrueType file is assembled byte by byte in JS — glyf, loca, cmap, hmtx, name and friends — with recalibrated checksums.
Double-click the download to install it, or drop it into Figma, Word and Google Docs. Advance widths stay untouched, so kerning still behaves.
Why it behaves
Noise is hashed from style + intensity + glyph index, so the same settings always rebuild the same file. Randomize re-rolls the settings, never the maths.
You get genuine quadratic-friendly TrueType contours with a proper cmap, so the glyphs stay crisp at any size and are editable in font editors.
There is no /api route in this tool at all. The outlines, the distortion and the file writing all happen in your browser tab.
Only outline points move; hmtx metrics are copied from the base face, so paragraphs keep their rhythm instead of collapsing.
The base outlines are traced once and cached, so dragging the intensity slider only re-displaces points and re-writes a small preview font.
The base is your device's own serif face, so nothing commercial is copied — 'Times New Bastard' here is an approximation, not a clone.
FAQ
Does it really output an installable font?
Yes — a TrueType (.ttf) file written byte by byte in your browser. Download it, double-click to install on macOS or Windows, or drag it into Figma, Word or Google Docs.
Why do two downloads with the same settings look identical?
They are identical, byte for byte. Every displacement is seeded from a hash of the style and intensity, so nothing is left to chance. The family name carries a short settings hash to dodge OS font caching.
What happens to CJK, Cyrillic or emoji in my sample?
The base face has no glyphs for them, so those characters render in your browser's fallback font in the preview and are absent from the .ttf. The generated font covers Latin-1 (about 190 glyphs).
Why does intensity 10 look broken?
At amplitude 10 outline segments can cross each other, and a rasteriser fills the crossings with hairline spikes. That is the point, but 6–7 is usually where 'cursed but usable' lives.
My preview lags a slider tick behind on iOS.
Safari registers a freshly created FontFace asynchronously, so the specimen shows a 'rebuilding…' shimmer for a beat. Chrome, Firefox and desktop Safari snap instantly.
What if the outline trace fails on my device?
The tool needs canvas text rendering and the CSS Font Loading API. If either is blocked (some privacy extensions do), the specimen panel says so plainly instead of showing an empty box.
Can I edit the result?
Open it in FontForge, Fontra or Glyphs — the contours are ordinary TrueType outlines, though they arrive with a lot of points because they started life as traced pixels.
The .ttf is generated locally in your browser — no upload, no server, no account — and non-Latin characters simply fall back to the base font.