mado
mado (窓, "window") is a TUI markdown viewer written in Go, built on
Bubble Tea and
Glamour.

Features
- Markdown rendering in the terminal via Glamour
- Reader / source modes — toggle between a clean document view and syntax-highlighted raw markdown with one key
- Inline image preview — PNG/JPEG/GIF files render as half-block pixel art fitted to the pane
- Sidebar file tree rooted at the current directory (lazy-loaded, collapsible;
a toggles between markdown-only and all files)
- Multiple open files — each file opens in its own tab
- Mouse support — click files to open, click tabs to switch, click
✕ to close, scroll wheel in both panes
- Auto-reload —
--watch re-renders open files as they change on disk, so mado can sit in a pane as a live view
- Remote commands —
mado --remote open FILE adds a tab to the instance already on screen instead of starting a second one
- TOML configuration —
~/.config/mado/config.toml
- Configurable keyboard shortcuts — every action can be rebound
- Theme customization — Glamour styles (
auto, dark, light, dracula, or your own style JSON) plus UI colors and a source_style for source-mode highlighting
Install
Download a prebuilt binary for Linux, macOS, or Windows from the
releases page, or
install with Go:
go install github.com/hidekingerz/mado@latest
Or build from source:
git clone https://github.com/hidekingerz/mado.git
cd mado
go build -o mado .
Usage
mado # browse markdown files under the current directory
mado docs/ # root the sidebar at docs/
mado README.md a.md # open files in tabs immediately
mado --watch TASKS.md # reload automatically when the file changes
mado --remote open notes.md # add a tab to a running mado
mado -style dracula # override the markdown theme
mado -config my.toml # use an alternate config file
mado -version # print the version
View modes
There are two ways to look at a file, switched with m:
- Reader (default) — markdown rendered as a clean document. Heading
markers (
##) are hidden; levels are distinguished by color,
underline, and italics.
- Source — the raw markdown text, for checking the syntax itself.

The startup mode can be set with default_mode = "source" in the
config.
Auto-reload
By default files are re-read only when you press r / F5. With
--watch (or watch = true in the config) mado watches the open files
and the sidebar directories and reloads them as soon as they change,
keeping your scroll position. [WATCH] in the status bar shows it is
on.
This is what makes mado usable as a live dashboard: leave it open on a
plan or a log file that another process keeps rewriting, and the pane
follows along. Rapid successive writes are coalesced, so a burst of
saves costs one reload.
What a file says is shown, never obeyed: control characters are drawn
in caret notation (^[ for escape) rather than passed to the terminal,
so a file cannot set your clipboard, rewrite the window title, or move
the cursor to overwrite what is on screen. That holds for file names in
the sidebar too. It is why an ANSI-coloured log shows its escape codes
as text instead of colours.
Default key bindings
| Key |
Action |
↑/k, ↓/j |
move cursor / scroll |
enter/l |
open file / expand directory |
esc/h |
focus the sidebar |
tab/] |
next tab |
shift+tab/[ |
previous tab |
x/ctrl+w |
close tab |
b/ctrl+b |
toggle sidebar |
ctrl+d/ctrl+u |
half page down / up |
g/G |
go to top / bottom |
r/F5 |
reload tree and current file |
m |
toggle reader / source mode |
a |
show all files / markdown only |
? |
help |
q/ctrl+c |
quit |
Mouse
- Click a file in the sidebar to open it; click a directory to expand or collapse it.
- Click a tab to switch to it; click the
✕ on a tab to close it.
- Scroll wheel scrolls whichever pane is under the pointer.
Remote commands
A running mado accepts commands from other processes, so a script, an
editor hook, or a terminal multiplexer plugin can put a file in front
of you without opening a second viewer:
mado --remote open docs/plan.md # add a tab (or switch to it if already open)
mado --remote focus docs/plan.md # switch to the file's tab; fails if it is not open
If no instance is running, --remote open starts one with those files
— so it is safe to use unconditionally. --remote focus never opens a
file in an existing instance; it only moves between what is already
there.
Each instance listens on a Unix socket named after its pid, under
$XDG_RUNTIME_DIR/mado (a private directory under the system temp dir
when XDG_RUNTIME_DIR is unset). Commands go to the most recently
started instance that answers; set MADO_SOCKET to a socket path to
pin both ends to one instance:
MADO_SOCKET=/tmp/mado-notes.sock mado notes/ # this instance…
MADO_SOCKET=/tmp/mado-notes.sock mado --remote open notes/today.md # …gets the file
The socket directory is a trust boundary: anything a command opens, it
opens as you. mado creates it private and, if it is already there,
checks that it belongs to you and that no other user can write to it —
on a shared machine with no XDG_RUNTIME_DIR, the directory name is
predictable enough for someone else to create first and plant a socket
in. A directory that does not pass turns remote commands off for that
instance, with a line on stderr saying why; everything else about mado
still works.
Configuration
mado reads $XDG_CONFIG_HOME/mado/config.toml (default
~/.config/mado/config.toml). Every key is optional; unset values fall
back to the defaults. See config.example.toml
for the full annotated reference.
[general]
watch = false # true = auto-reload files when they change
[theme]
style = "dracula" # glamour style name or path to a style JSON
accent_color = "#7C6AEF"
dir_color = "#89B4FA" # sidebar directory names
file_color = "#FFFFFF" # sidebar text files (known binaries are dimmed)
[sidebar]
width = 32
show_all_files = false # true = list non-markdown files too
show_hidden = false
[keys]
quit = ["q", "ctrl+c"]
open = ["enter", "l"]
next_tab = ["tab", "]"]
# … any action from config.example.toml
License
Apache-2.0