Franking

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.

Native IMAP/SMTP Local SQLite store PGP & S/MIME Multi-account Ratatui TUI

Built for triage, not just reading

Folders and messages

Core

Unread 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

MIME

Structured 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

Authoring

Reply, 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

Workflow

Screening, 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

Trust

Discovery, 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.

Repository

Source and setup

↑