A terminal email client that owns its mail layer—native IMAP/SMTP transport, a local SQLite store, and a keyboard-driven workflow built for real triage.
Franking is a ratatui TUI email client with an app-owned mail layer. Accounts, endpoints, auth bindings, and secret references live in SQLite; raw secrets stay in the OS keyring. A shared MIME parser produces one canonical view of a message, and a background worker pool keeps every mail operation off the render path.
Built for triage, not just reading
Folders and messages
CoreUnread counts, per-account folders, threaded or flat
Server-side ordering with a local cache, relative timestamps, mouse support, and an "All Inboxes" folder that merges every account's inbox when more than one is configured.
Reader
MIMEStructured content, attachments, invitations
Raw messages are parsed once and rendered as structured content with one canonical HTML-first path. Attachments preview in place, save individually, or write out as an archive, and text/calendar events show their summary and timezone and can be handed to Planner123.
Compose
AuthoringReply, forward, attachments, drafts
A single authoritative input router resolves focus buckets, popups, and shortcuts in a deterministic precedence order, so modal interactions stay predictable. PGP and S/MIME toggles sit beside snippets, in-body search, and save-as-draft.
Triage lanes
WorkflowScreening, follow-up, quiet conversations
An inbox cycles through Screening, Inbox, Reading, Receipts, and Blocked, and 1–5 routes a sender for the receiving account. Follow-up queues, quiet and resurfacing timers, local annotations, sender bundles, and workflow stages keep a high-volume mailbox operable without leaving the keyboard.
Accounts and secrets
TrustDiscovery, SQLite metadata, OS keyring
Add an account by email: Google, iCloud, and Outlook presets, then Mozilla autoconfig, Microsoft Autodiscover, and RFC 6186 SRV. SQLite stores definitions, endpoints, auth bindings, and secret references; the raw secrets stay in the OS keyring. Versioned migrations preserve local decisions and fail safely on an unsupported database.
Screenshots
Every image below is the running application, rendered from its own cell grid with the colours it chose.

Architecture
graph TD
TUI[Ratatui TUI - Elm architecture] --> Worker[Async worker pool]
Worker --> Service[MailService trait]
Service --> IMAP[Native IMAP]
Service --> SMTP[Native SMTP]
Service --> Maildir[Local maildir]
Service --> DB[(SQLite: accounts, contacts, identities)]
Service --> Keyring[OS keyring: secrets]
Service --> MIME[Shared MIME parser]
An app-owned mail layer
OpenPGP (inline and PGP/MIME) and S/MIME (PKCS#7 signed and enveloped) verify and decrypt against a local keyring, and SPF, DKIM, and DMARC verdicts are surfaced from Authentication-Results. Live integration tests run Dovecot and Mailpit in throwaway containers, and the local test maildir account works with no network and no external dependencies.