ASCII Art Generator Guide: Figlet Fonts, Box Drawing, and CLI Banners
ASCII art is not a relic. In 2026, it still appears in startup banners for CLI tools, separators in CI build logs, README headers on open-source projects, and package install messages. When rendered in a monospace terminal it costs zero dependencies on the reader's side and survives copy-paste into any plain-text medium. Use the ASCII Art Generator to preview fonts and box-drawing styles as you work through this guide.
Where ASCII Art Still Earns Its Keep
Monospace art has a narrow but reliable set of legitimate uses in developer tooling:
- CLI startup banners. Tools like kubectl, Terraform, and Vault print a stylized name on first run or version output. It signals that the tool loaded correctly and gives a visual anchor before dense log output begins.
- CI build separators. A thick ASCII line between test suites in a GitHub Actions or Jenkins log makes it far easier to scan for failures. Plain text dashes work, but a Figlet header like
UNIT TESTSis impossible to miss. - README art. A project name rendered in a large font at the top of a README renders cleanly in raw form on GitHub, npm, and any terminal that clones the repo.
- Package install messages. npm postinstall scripts and Homebrew casks have long used ASCII banners to display license notices, quick-start commands, or deprecation warnings in a way that stands out from the rest of the install output.
- cowsay-style MOTD. Server login banners (Message of the Day) use ASCII art to display hostname, environment name (staging vs production), or uptime warnings in a format that is immediately visible before any command is run.
Outside these contexts, ASCII art in production application output or user-facing UI is almost always a distraction. The question is not whether ASCII art is cool — it is whether it carries information in that specific context.
Figlet: The Canonical ASCII Text Renderer
Figlet is the original program for rendering text as large ASCII characters. It was written in 1991 and its font format, .flf, remains the de facto standard used by every modern implementation.
A .flf file has two parts: a header line that describes the font's geometry (height in rows, baseline row, max width, hard blank character, and comment lines), followed by character definitions. Each character is stored as a fixed number of rows with a termination marker. The height property defines how many terminal rows each rendered character occupies — standard fonts are typically 6–8 rows tall.
Smushing is Figlet's kerning algorithm. When two characters are placed adjacent, smushing rules determine whether their edges can overlap. Strict smushing collapses matching characters (two | become one), while universal smushing always overlaps by one column. The result is tighter text at the cost of potential character ambiguity on certain font/character combinations.
# Install figlet (macOS / Linux)
brew install figlet # macOS
apt-get install figlet # Debian/Ubuntu
# Basic usage
figlet "Hello World"
# Choose a font
figlet -f slant "Deploy v2.0"
# List installed fonts
figlet -I2 # prints font directory path
ls $(figlet -I2)/*.flf | xargs -I{} basename {} .flfPopular Figlet Fonts
The Figlet font collection ships hundreds of typefaces. Most projects settle on a handful that balance legibility, width, and visual weight:
| Font | Height | Character | Best For |
|---|---|---|---|
| standard | 6 rows | Solid block letters | General purpose; most recognizable |
| big | 8 rows | Chunky, filled | Short words, high impact |
| slant | 6 rows | Italicized | Version banners, project names |
| banner3 | 6 rows | Uppercase block capitals | Warning/error headers |
| doom | 5 rows | Bold, compact | CI separators, narrower terminals |
| ansi-shadow | 6 rows | 3D shadow effect | README headers, splash screens |
When choosing a font, render your actual string first. Long words in big or ansi-shadow easily exceed 120 columns. Short words in doom often fit within 80.
Width Constraints
The single most common problem with ASCII banners is line wrapping. A Figlet render is just a block of text — there is no reflow. If the output is 140 characters wide and the terminal is 80 columns, every row wraps, destroying the font shape entirely.
Standard terminal widths to target:
- 80 columns — the historical default; still common in SSH sessions, legacy CI runners, and
lessoutput. - 120 columns — typical for modern terminal emulators and most CI log viewers (GitHub Actions renders at ~120).
- No assumption — if the banner will appear in arbitrary terminals, query
$(tput cols)or$COLUMNSat runtime and only print the banner if the terminal is wide enough.
Rule: test your banner at 80 columns before shipping. Use figlet -w 80 to force a width limit, or generate the art and pipe through fold -w 80 to verify no line exceeds it.
# Check max line length of a figlet output
figlet -f doom "Deploy" | awk '{ print length, $0 }' | sort -rn | head -1Box-Drawing Characters
Box-drawing characters are a separate but related concept. They are Unicode code points (U+2500 block) designed to draw table borders and frames in monospace environments.
| Style | Characters | Notes |
|---|---|---|
| Unicode single-line | ─ │ ┌ ┐ └ ┘ ├ ┤ ┬ ┴ ┼ | Renders correctly in most modern terminals |
| Unicode double-line | ═ ║ ╔ ╗ ╚ ╝ ╠ ╣ ╦ ╩ ╬ | High-impact borders; slightly less portable |
| ASCII fallback | - | + + + + | | - - + | Universal; works in every environment |
Cross-platform considerations: Unicode box-drawing characters render correctly in modern terminal emulators on macOS, Linux, and Windows Terminal. They break in Windows CMD (the legacy cmd.exe) and older PowerShell sessions that use the default code page 437 or 850. If your tool targets Windows developers who may run it in CMD, use ASCII fallbacks (-, |, +) or detect the terminal and choose accordingly.
// Node.js: choose box style based on terminal capability
const isUnicode = process.platform !== 'win32' || process.env.WT_SESSION;
const box = isUnicode
? { h: '─', v: '│', tl: '┌', tr: '┐', bl: '└', br: '┘' }
: { h: '-', v: '|', tl: '+', tr: '+', bl: '+', br: '+' };
function drawBox(text: string): string {
const width = text.length + 2;
const top = box.tl + box.h.repeat(width) + box.tr;
const middle = box.v + ' ' + text + ' ' + box.v;
const bottom = box.bl + box.h.repeat(width) + box.br;
return [top, middle, bottom].join('\n');
}Use Cases at a Glance
| Context | Recommended Approach | Width Budget |
|---|---|---|
| Login banner (MOTD) | Figlet doom or standard | 80 cols safe |
| CI log separator | Figlet header + Unicode ─ rule below | 120 cols OK |
| README header | Figlet ansi-shadow in a code block | No hard limit |
| Package install message | Short word, slant or doom | 80 cols safe |
| Deploy log header | Figlet + environment name + timestamp | 120 cols OK |
| 404 page (terminal UI) | Figlet big + ASCII border | Terminal width |
Generating Programmatically
Figlet ports exist for every major language. They all read the same .flf font files, so output is consistent across environments.
Node.js — figlet
npm install figletimport figlet from 'figlet';
// Synchronous
const banner = figlet.textSync('Deploy v2.0', {
font: 'Doom',
horizontalLayout: 'default',
verticalLayout: 'default',
width: 120,
whitespaceBreak: true,
});
console.log(banner);
// Async (loads font from disk)
figlet.text('Hello', { font: 'Slant' }, (err, result) => {
if (err) throw err;
console.log(result);
});Python — pyfiglet
pip install pyfigletimport pyfiglet
# Single call
print(pyfiglet.figlet_format("Deploy", font="doom"))
# With width constraint
f = pyfiglet.Figlet(font="slant", width=80)
print(f.renderText("v2.0.1"))Go — go-figure
go get github.com/common-nighthawk/go-figurepackage main
import "github.com/common-nighthawk/go-figure"
func main() {
myFigure := figure.NewFigure("Deploy", "doom", true)
myFigure.Print()
// With color (ANSI)
colorFigure := figure.NewColorFigure("OK", "doom", "green", true)
colorFigure.Print()
}Color and ASCII
ANSI escape codes let you colorize ASCII art without any external dependency. The escape sequence \x1b[<code>m sets the text color; \x1b[0m resets it.
// Node.js with chalk (handles truecolor / 256-color / 16-color fallback)
import chalk from 'chalk';
import figlet from 'figlet';
const art = figlet.textSync('READY', { font: 'Doom' });
console.log(chalk.green(art));
// Manual ANSI (no deps)
const GREEN = '\x1b[32m';
const RESET = '\x1b[0m';
console.log(GREEN + art + RESET);Color compatibility tiers to be aware of:
- 16-color ANSI — works everywhere, including SSH sessions without terminal capability negotiation and Windows CMD with ANSI enabled.
- 256-color — supported by xterm-256color and most modern terminal emulators. Check
$TERMor$COLORTERMbefore using. - Truecolor (24-bit) — requires
COLORTERM=truecolor. Supported by iTerm2, Windows Terminal, and most Linux emulators since 2018. Silently degrades in unsupported terminals.
Libraries like chalk (Node), colorama (Python), and fatih/color (Go) detect the terminal's color capability at runtime and downgrade automatically, which is the correct approach for tools intended to run in diverse environments.
Common Pitfalls
- Non-monospace fonts break alignment. ASCII art assumes every character occupies exactly one column. If your terminal or editor uses a proportional font (even partially, via ligature substitution), box-drawing characters and Figlet art lose their shape. Always preview in a proper monospace environment.
- Windows Terminal vs CMD vs PowerShell. Windows Terminal renders Unicode box-drawing and ANSI color correctly. Legacy CMD does not, unless the code page is set to 65001 (
chcp 65001). PowerShell in older versions strips ANSI codes. Never assume a Windows user has Windows Terminal. - RTL text. Arabic, Hebrew, and other right-to-left scripts produce unreadable output in Figlet — the character order is reversed, and the font maps only ASCII/Latin code points. Figlet is not an appropriate tool for non-Latin scripts.
- Emoji width ambiguity. Emoji characters are typically double-width in terminals (they occupy two columns), but this depends on the terminal's Unicode width tables and whether the font handles them. Mixing emoji with box-drawing characters in the same row causes misalignment in most environments. Keep ASCII art zones free of emoji.
- Long text wraps badly. Words longer than about 8–10 characters in large fonts exceed 80 columns. Abbreviate or split across two lines rather than letting the terminal wrap mid-character.
Generate and preview ASCII art directly in your browser using the ASCII Art Generator — choose from standard Figlet fonts, preview box-drawing styles, and copy the result ready for your next banner or CI step. For more text manipulation tools, see the Text Tools Guide.