A terminal email client for Linux maildirs, written in Rust.
epost reads mail that mbsync (or any other maildir writer) put on disk and
sends by piping to msmtp. It has no IMAP or SMTP implementation of its own.
HTML mail is a first-class citizen: bodies are parsed with html5ever and
rendered into the terminal cell grid, with a Vimium-style link picker, inline
images via the terminal's image protocol, and an :open escape hatch to the
system browser for the messages a cell grid can't do justice to.
Status: pre-1.0 and under active development. Usable, but expect rough edges and changing defaults.
- Vim-style modal input throughout: reader, message list, and composer.
- Four-pane layout (folders, message list, reader, cmdline) with a unified inbox across accounts.
- Maildir is the source of truth; the SQLite index is a disposable cache that can be deleted and rebuilt at any time.
- Live
inotifywatching, so external syncs show up without a restart. - Threaded message list, flags, cross-folder moves with undo, search.
- Compose with attachments, address completion, and a native vim-style body
editor (or your
$EDITORunder a pty). - Remote content is never fetched, and nothing in the HTML path can execute code.
- Linux, a recent Rust toolchain.
mbsync(or equivalent) to fetch mail, andmsmtpto send it.- A terminal supporting the kitty graphics protocol, iTerm2 inline images, or sixel for inline images; anything else falls back to half-blocks or placeholders.
With Nix:
nix run github:jolars/epostFrom source:
cargo install --path .epost reads ~/.config/epost/config.toml (strictly: unknown keys are an
error) and never writes it. A minimal config:
[accounts.personal]
maildir = "~/Mail/personal"
from = "Jane Doe <jane@example.com>"
sent = "Sent"
archive = "Archive"
trash = "Trash"
[smtp]
command = ["msmtp", "-t"]
[sync]
# Optional: what `:sync` runs. Omit if you drive mbsync from a timer.
command = ["mbsync", "-a"]See the Configuration section of DESIGN.md for the full
schema.
CLI flags: --config <path> and --cache <path> override the config and index
locations.
The devshell (Rust toolchain, bacon, mbsync, msmtp, cargo-insta) comes
from devenv.nix; run direnv allow to activate it. All commands go through
go-task:
task dev # main loop, auto-rebuilding against dev/config.toml
task run # one-shot run against the dev config
task ci # fmt:check + lint + test
task --list # everything elsedev/ holds an in-repo fixture maildir and stub msmtp/browser scripts, so
development never touches real mail.
DESIGN.md is the authoritative architecture document,
AGENTS.md tracks implementation state, and TODO.md
lists what's next.