Back to Articles

Glow: How Charm Built a Markdown Reader That Feels Like a Native Terminal App

[ View on GitHub ]

Glow: How Charm Built a Markdown Reader That Feels Like a Native Terminal App

Hook

Most CLI tools treat markdown rendering as a one-way pipe: text goes in, ANSI codes come out. Glow flipped this model by building a stateful TUI that makes reading documentation feel as natural as using less or vim.

Context

Documentation lives in markdown, but reading it has always been awkward. You either context-switch to a browser (GitHub’s rendered view), suffer through raw markdown in your editor, or pipe files through basic converters that ignore your carefully-tuned terminal colorscheme. Developers who live in the terminal face a choice: stay in your workflow and read ugly docs, or leave the terminal entirely.

Glow emerged from Charm’s philosophy that terminal applications deserve the same design attention as GUI apps. Rather than treating the CLI as a second-class citizen, the team built an entire ecosystem (Bubble Tea for TUIs, Glamour for markdown rendering, Lipgloss for styling) to make terminal apps genuinely delightful. Glow is the flagship demonstration: a markdown reader that discovers files intelligently, renders them beautifully, and stays completely within your terminal workflow.

Technical Insight

markdown content

file list

CLI flag

no args

markdown

selected file

theme request

light/dark/custom

ANSI styled output

CLI

TUI

style override

Input Source

File/Stdin/URL/Git

Markdown Discovery

Directory/Git/Remote

Execution Mode

CLI Mode

Unix Filter

TUI Mode

Bubble Tea

Glamour Renderer

Theme Detection

Terminal Background

Output

stdout

Interactive Pager

vim-like navigation

Config Files

YAML/JSON styles

System architecture — auto-generated

Glow’s architecture splits cleanly into two modes that share a common rendering core. The CLI mode operates as a traditional Unix filter—read from file, stdin, or URL, render to stdout—while the TUI mode appears to layer an event-driven interface on top. Both paths funnel through Glamour, which transforms markdown into ANSI-styled output.

The interesting architectural decision is theme detection. Glow doesn’t force you to manually configure light versus dark styles. Instead, it attempts to detect your terminal’s current background color and automatically picks either the dark or light style. You can override this with the -s flag:

# Auto-detect terminal background and choose style
glow README.md

# Explicitly use dark theme
glow -s dark README.md

# Use custom JSON stylesheet
glow -s ~/.config/glow/monokai.json README.md

The TUI mode is where the interactive experience shines. When you run glow without arguments, it enters an interactive file browser that discovers markdown files in the current directory and subdirectories or, if you’re in a Git repository, searches the repo. The browsing interface allows navigation through local files. Most keystrokes from less work, and pressing ? reveals the full hotkey list.

File discovery appears to respect .gitignore rules by default—hidden files and ignored paths won’t appear unless you pass --all. For remote content, Glow has special handling for GitHub and GitLab URLs:

# Automatically fetches README.md from the repo
glow github.com/charmbracelet/glow

# Also works with GitLab
glow gitlab.com/owner/project

# Raw HTTP works too
glow https://example.com/docs/guide.md

The pager implementation is described as high-performance. Rather than always shelling out to less, Glow implements its own pager. This gives it control over rendering: word wrapping respects the -w flag, and line numbers can be toggled in TUI mode via config. However, if you prefer your system pager, the -p flag pipes output to $PAGER (defaulting to less -r for ANSI support).

Configuration lives in glow.yml, which you edit via glow config. The config file uses a simple YAML structure that maps directly to CLI flags:

style: "dark"
mouse: true
pager: false
width: 100
all: false
showLineNumbers: true
preserveNewLines: false

This design pattern—CLI flags that mirror config options—means you can quickly test settings before committing them to the config file. The width parameter is particularly useful: it sets a maximum width at which output will be wrapped, preventing markdown from becoming unreadable on ultra-wide monitors. Setting width: 80 gives you classic terminal column discipline, even if your terminal is fullscreen on a 4K display.

Gotcha

Glow’s primary limitation is that it’s strictly a reader, not an editor. You can’t modify markdown files in the TUI. If you need to make changes, you’ll still context-switch to your editor. The tool assumes you have a modern terminal emulator with full ANSI color support; on truly basic terminals (think headless SSH to ancient systems), the styling may degrade significantly.

Network-fetched content introduces external dependencies. When fetching remote content, you’re relying on network availability and the remote server’s responsiveness. The tool makes fresh requests for remote URLs, so for frequently accessed documentation, you’re better off cloning locally.

While Glow handles standard markdown well, complex formatting edge cases may render differently than expected. If your documentation relies heavily on intricate layouts or specific rendering quirks, you should verify that Glow’s output meets your needs. The Glamour rendering engine prioritizes readability for prose-heavy documents.

Verdict

Use Glow if you spend most of your day in the terminal and want documentation reading to match the quality of your other CLI tools. It’s ideal for projects with extensive markdown docs, polyglot teams who need a consistent reading experience across platforms, or anyone maintaining a personal knowledge base in markdown. The TUI mode particularly shines when exploring unfamiliar codebases where you need to quickly browse multiple READMEs without leaving your workflow. Skip it if you primarily work in GUI editors with built-in markdown preview, need to annotate or edit documentation inline, or require highly specialized rendering for complex document layouts. Also consider alternatives if you’re on severely resource-constrained systems where a full Go binary might be too heavy.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/cybersecurity/charmbracelet-glow.svg)](https://starlog.is/api/badge-click/cybersecurity/charmbracelet-glow)