Map plain ASCII to Unicode "font" styles — bold, italic, script, fraktur, small caps, upside down and ten more. Zero dependencies, no DOM, ~150 lines.
There is no such thing as a bold font in a plain-text field. What tools like this
actually do is swap each letter for a different Unicode code point that happens
to look bold — mostly from the Mathematical Alphanumeric Symbols block. That is
why the result survives a copy-paste into a bio, a chat message or a filename,
and also why a screen reader will read 𝐛𝐨𝐥𝐝 as "mathematical bold small b, …".
Use it for a display name, not for body text.
This is the engine behind the Toolerax fancy text generator, pulled out as a standalone module.
npm install @toolerax/fancy-textimport { stylize, stylizeAll, FANCY_STYLES } from "@toolerax/fancy-text";
stylize("Toolerax", "bold"); // 𝐓𝐨𝐨𝐥𝐞𝐫𝐚𝐱
stylize("Toolerax", "smallCaps"); // Tᴏᴏʟᴇʀᴀx
stylize("Toolerax", "upsideDown"); // xɐɹǝloo⊥
// Render every style at once — for a "pick one" list.
stylizeAll("hi");
// [{ id: "bold", label: "Bold", text: "𝐡𝐢" }, …]
// Or drive the style table yourself.
FANCY_STYLES.map((s) => s.id);| id | Label | Toolerax 123 |
|---|---|---|
bold |
Bold | 𝐓𝐨𝐨𝐥𝐞𝐫𝐚𝐱 𝟏𝟐𝟑 |
italic |
Italic | 𝑇𝑜𝑜𝑙𝑒𝑟𝑎𝑥 123 |
boldItalic |
Bold Italic | 𝑻𝒐𝒐𝒍𝒆𝒓𝒂𝒙 123 |
script |
Script (cursive) | 𝒯ℴℴ𝓁ℯ𝓇𝒶𝓍 123 |
boldScript |
Bold Script | 𝓣𝓸𝓸𝓵𝓮𝓻𝓪𝔁 123 |
fraktur |
Fraktur (gothic) | 𝔗𝔬𝔬𝔩𝔢𝔯𝔞𝔵 123 |
doubleStruck |
Double-struck (outline) | 𝕋𝕠𝕠𝕝𝕖𝕣𝕒𝕩 𝟙𝟚𝟛 |
monospace |
Monospace | 𝚃𝚘𝚘𝚕𝚎𝚛𝚊𝚡 𝟷𝟸𝟹 |
sansBold |
Sans-serif Bold | 𝗧𝗼𝗼𝗹𝗲𝗿𝗮𝘅 𝟭𝟮𝟯 |
circled |
Circled | Ⓣⓞⓞⓛⓔⓡⓐⓧ ①②③ |
squared |
Squared | 🅃🄾🄾🄻🄴🅁🄰🅇 123 |
fullwidth |
Fullwidth (vaporwave) | Toolerax 123 |
smallCaps |
Small Caps | Tᴏᴏʟᴇʀᴀx 123 |
upsideDown |
Upside Down | ƐᄅƖ xɐɹǝloo⊥ |
strikethrough |
Strikethrough | T̶o̶o̶l̶e̶r̶a̶x̶ 1̶2̶3̶ |
underline |
Underline | T̲o̲o̲l̲e̲r̲a̲x̲ 1̲2̲3̲ |
Rows where 123 comes out unchanged are not bugs — Unicode has no italic,
script or fraktur digits, so they are left alone rather than faked from another
block.
Background on why any of this works: How fancy text actually works.
- Anything unmapped passes through unchanged. Accented letters, CJK, punctuation and emoji come out as they went in.
- Iteration is by code point, so surrogate pairs are never split —
🙂survives every style. smallCapsdeliberately leaves uppercase alone. The small-caps block only covers lowercase; faking the rest would look worse than leaving it.upsideDownreverses the string as well as flipping each glyph, which is what makes it read correctly when the reader turns their head.- Combining styles skip whitespace.
strikethroughandunderlineappend a combining mark (U+0336 / U+0332), and adding one to a space produces a stray floating bar in most fonts. - Rendering is the font's problem, not this library's. Some of these blocks
are patchy in system fonts, and
squaredin particular renders as emoji-style tiles on some platforms and flat boxes on others.
| Export | Signature |
|---|---|
stylize |
(text: string, id: string) => string — throws RangeError on an unknown id |
stylizeAll |
(text: string) => Array<{ id, label, text }> |
applyStyle |
(text: string, style: StyleDef) => string — for a hand-built style |
getStyle |
(id: string) => StyleDef | undefined |
FANCY_STYLES |
StyleDef[] — every style, in display order |
StyleDef |
the style-definition type |
npm install
npm test # builds, then runs the node:test suiteMIT © Toolerax