A reading-focused terminal markdown viewer — more like "Reader Mode in your terminal" than a markdown-as-markdown renderer.
Glum optimizes for reading prose, not decorating syntax. Headings become
typographic styles, not # prefixes; links show their URL inline so you can
see and click them; code blocks are framed with rules and highlighted; tables
wrap rather than truncate; the file scrolls a page at a time like less.
curl -fsSL https://raw.githubusercontent.com/jaschadub/glum/main/scripts/install.sh | bashThis downloads the latest signed release archive for your platform, verifies
its SHA-256, and installs glum into $HOME/.local/bin. Override the prefix
with GLUM_PREFIX=/usr/local, pin a version with GLUM_VERSION=v0.2.2.
cargo install glumEvery release attaches
signed .deb and .rpm packages for x86_64 and aarch64. Install
directly:
# Debian / Ubuntu (pick the arch for your machine)
curl -LO https://github.com/jaschadub/glum/releases/latest/download/glum_0.2.2-1_amd64.deb
sudo apt install ./glum_0.2.2-1_amd64.deb
# Fedora / RHEL / openSUSE
sudo dnf install https://github.com/jaschadub/glum/releases/latest/download/glum-0.2.2-1.x86_64.rpmBoth packages install the binary to /usr/bin/glum, the man page to
/usr/share/man/man1/, and completions under the usual shell-specific
XDG directories — no further setup needed.
Not yet. Use cargo or the install.sh one-liner. On Windows, grab the
.zip from the releases page
or use cargo install glum.
cargo build --release
./target/release/glum test.mdEvery release archive and checksums.txt is signed with
Sigstore cosign via GitHub Actions OIDC
(keyless). Verify with:
cosign verify-blob \
--certificate glum-*.pem \
--signature glum-*.sig \
--certificate-identity-regexp="https://github.com/jaschadub/glum" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
glum-*.tar.gz- Reader layout — narrow, centered measure (default 72 cols), five
themes (
T), two typographic layouts (L), three alignments (A). All toggle at runtime and are remembered across runs. - Code blocks — syntax highlighting for 12 languages, top/bottom
rules with a language label, no side borders. Long lines soft-wrap
with
↪or truncate with…(W). - Copy —
ythe block,Ypick a single source line,Ropen a full-screen raw view with horizontal pan. Copies always come from the original source, so no↪or…leaks. Uses native clipboard (pbcopy/wl-copy/xclip/xsel) when available, OSC 52 otherwise. - Tables wrap long cells instead of truncating, keep column
separators aligned, and draw
╌row separators when any row wraps. - Links render inline URLs for external and relative paths; anchor links stay clean.
- Search (
/) with live match count andn/N/ Tab stepping. - TOC (
t) overlay; jump to first match of a heading title with-H. - Editor handoff —
eopens$EDITOR/$VISUALat the nearest heading's source line, then reloads. - Follow mode (
-f) re-renders on file change;rreloads manually. - Per-file position memory, hashed paths, atomic writes. Opt out
with
--no-remember. - Optional mouse scroll (
--mouse) — off by default so the terminal's native text selection keeps working. - Smart typography (
"..."→“…”,--→—,...→…). - Terminal-safe panic handler — a crash still restores your shell.
- Bounded inputs — 64 MiB file cap; 256-char search cap.
glum [OPTIONS] <PATH>
--measure <N> column width (20..200, default 72)
--theme <NAME> light, dark, sepia, night, plain
--layout <NAME> minimal or vivid
--align <NAME> center, left, or right
-s, --search <QUERY> open with search pre-populated; jump to first match
-H, --heading <TITLE> jump to first heading containing TITLE (case-insensitive)
--toc open with the table of contents overlay visible
--reset-position ignore saved position; start at the top
--truncate-code truncate long code lines with `…` instead of soft-wrapping
--no-remember don't persist reading position / preferences across runs
--mouse enable mouse-wheel scrolling (disables native text selection)
-f, --follow re-render when the file changes on disk
--generate-completions <SHELL> emit a shell completion script to stdout (bash/zsh/fish/elvish/powershell)
--generate-man emit a roff man page to stdout
Every release tarball ships completions and a man page alongside the binary:
share/bash-completion/completions/glum
share/zsh/site-functions/_glum
share/fish/vendor_completions.d/glum.fish
share/man/man1/glum.1
A packager can rsync share/ straight under a prefix (/usr/local/ or
similar). Installing by hand from a cargo install build:
glum --generate-completions bash > ~/.local/share/bash-completion/completions/glum
glum --generate-completions zsh > "${fpath[1]}/_glum"
glum --generate-completions fish > ~/.config/fish/completions/glum.fish
glum --generate-man > ~/.local/share/man/man1/glum.1If --theme, --layout, or --align is omitted, the last value you used is
restored. First-run defaults: minimal / center, plus light or
dark based on the terminal's advertised background (via $COLORFGBG,
falling back to dark).
Pass - as the path to read from stdin.
Examples:
glum README.md # just read
glum -s needle test.md # open, search for "needle"
glum -H "Code blocks" test.md # jump to a specific heading
glum --toc test.md # open with TOC visible
glum --theme light --measure 80 foo.md
glum --layout vivid --align left doc.md
glum -f README.md # auto-reload on save while editing
cat post.md | glum - # read from stdin
| key | action |
|---|---|
| j / ↓ | scroll down |
| k / ↑ | scroll up |
| space / PgDn | page down |
| b / PgUp | page up |
| d / u | half page down / up |
| g / G | top / bottom |
| t | table of contents |
| / | open search |
| n / N / Tab / → / ← | next / previous search match |
| c | clear active search |
| y | copy the in-view code block to clipboard |
| Y | pick a single code line to copy (j/k, Enter) |
| R | raw code view — no wrap, h/l pans, y copies |
| r | reload the current file from disk |
| e | open in $EDITOR at the nearest heading |
| T | cycle theme |
| L | cycle layout (minimal ↔ vivid) |
| A | toggle align (center → left → right) |
| W | toggle code wrap / truncate |
| ? | toggle help overlay |
| q / Esc | quit (reading) or close overlay |
| Ctrl-C | force quit from any mode |
Glum remembers where you were in each file and what theme / layout / align /
wrap-mode you were using. State lives at $XDG_STATE_HOME/glum/positions.json
(or ~/.local/state/glum/ as fallback). Paths are hashed with SHA-256 before
being stored, so the state file does not reveal which files you've read. The
file is written atomically with mode 0600. Pass --no-remember to opt out
of all persistence, or --reset-position to ignore the saved offset just for
the current run.
Apache License, Version 2.0. See LICENSE and NOTICE.
Copyright © 2026 Jascha Wanger (https://jascha.me).
