MIT Rust TUI + CLI

Modal-vim
email.

IMAP, SMTP, Gmail, Outlook, JMAP. One client, every inbox.

Maildir on disk. SQLite index. hjkl-powered composer.

inbx — me@fastmail.com
INBOX 12 Sent Drafts 2 Archive Spam [Gmail]/All
  • GitHub PRkryptic-sh/inbx #42 — wire IMAP IDLE socket 2m
  • Linus T. Re: Maildir layout — looks fine, ship it 14m
  • Fastmail JMAPYou have 3 new messages 1h
  • · cron daemon [backup] nightly snapshot complete (124 GB) 3h
  • · Stripe workReceipt for invoice #INV-2026-0418 yest
  • · rust-announce Rust 1.95.0 released — let-chains stabilized 2d
NORMAL j/k move · Enter open · c compose · r reply · / search · ? help ● fastmail (idle)

why

An email client shaped like vim, not Outlook.

01 — INPUT

Modal everything

Vim navigation through the list and the reader — j/k, h/l, gg/G, Tab between panes — and a composer that is a real modal editor, with its own motions, text objects and ex commands.

02 — KEYS

One keymap table

Every chord lives in a single data-driven bind table — the dispatcher and the ? help overlay read the same rows, so no key is defined twice. / runs an FTS search with n/N, m and y open move / copy pickers, <Space>F does folder create-rename-delete, and <Space>R marks a whole folder read.

03 — PROVIDERS

Multi-provider, one client

IMAP/SMTP, Gmail XOAUTH2, Microsoft Graph, JMAP. One config, every account. Provider abstracted behind a trait.

04 — STORAGE

Maildir + SQLite + FTS5

On-disk Maildir per account. SQLite index in WAL mode (TUI + sync hold the DB concurrently), with an FTS5 full-text index over subject / from / to / body. JWZ §2 threading, mailing-list bracket tags stripped. Offline-first.

05 — COMPOSE

hjkl-powered composer

Composer embeds hjkl — the same modal editor. Headers and body share one FSM. MIME built with mail-builder. <Space>t opens a template picker; PGP key lookup runs inline.

06 — FOLDERS

Multi-folder sync · friendly names

Each cycle syncs every server folder; IMAP IDLE / JMAP push triggers a full re-sync. [Gmail]/Trash renders as Trash, \Noselect virtual parents hidden. Two-line message rows: sender on top, subject below.

07 — DAEMON

inbx-sync IPC daemon

Optional inbx-sync daemon (or inbx sync subcommand) runs the IDLE / fetch / indexing loop out of process. TUI auto-detects via unix-socket IPC; falls back to in-process sync when the daemon isn't running.

08 — DAV

CalDAV + CardDAV + Sieve

Two-way CalDAV via inbx cal put|delete|rsvp. CardDAV auto-push on contact upsert. ManageSieve overlay caches the session across list/get/put. Etag-aware delta fetches.

09 — PGP

PGP — gpg or local keys

Per-account pgp.key_source picks between the system GnuPG keyring or inbx-managed keys on disk. Composer signs and encrypts inline, via rpgp. Public keys resolve over WKD; Autocrypt 1.1 headers are harvested on sync, so a correspondent advertising prefer-encrypt=mutual gets encrypted replies by default.

10 — SECURITY

TLS or nothing

Implicit TLS or STARTTLS only. Never falls through to plaintext. Remote content blocked by default. HTML sanitized via ammonia. Keyring backend selected per platform — no mock-keystore fallback.

11 — TRUST

Who actually sent this

The reader parses the Authentication-Results header (RFC 8601) and surfaces the SPF / DKIM / DMARC verdicts next to a handful of cheap phishing signals, flags 1×1 tracker pixels and known beacon hosts by name, and detects PGP / S/MIME parts. Read receipts are RFC 8098 MDNs, and List-Unsubscribe supports RFC 8058 one-click.

providers

Whatever you use, inbx talks to it.

IMAP + SMTP
Fastmail, Proton Bridge, dovecot, iCloud, Yahoo, Yandex. IMAP IDLE for push.
Gmail / Workspace
IMAP + SMTP via XOAUTH2. Auth-code flow with refresh tokens in the OS keyring.
Outlook / M365
OAuth2 IMAP/SMTP, or native Microsoft Graph (/me/messages, /me/sendMail) with delta sync. Tenant-aware.
JMAP
Fastmail, Stalwart. Fewer round-trips, push native. Preferred when the server speaks it.

install

Prebuilt binaries on every tagged release.

macOS via Homebrew tap, Arch via AUR, Alpine .apk, or grab a prebuilt binary. Linux x86_64 (glibc 2.28 and musl) — .tar.gz. macOS, Apple Silicon and Intel — .tar.gz. Windows x64 — .zip. SHA-256 sidecars on every artifact. More targets land as the workspace stabilises.

inbx — macOS (Homebrew)
$ brew install kryptic-sh/tap/inbx
$ inbx
inbx — Arch Linux (AUR)
$ yay -S inbx-bin
$ paru -S inbx-bin

# installs inbx + inbx-sync to /usr/bin/, auto-tracks tagged releases
inbx — Alpine Linux
$ # download .apk from releases page, then:
$ apk add --allow-untrusted inbx-*.apk
$ inbx
inbx — from source
$ git clone https://github.com/kryptic-sh/inbx
$ cd inbx
$ cargo build --release

# binaries in target/release/{inbx,inbx-sync}