localmail mirrors every IMAP account you own into a local PostgreSQL database and a content-addressable file tree. Searchable, scriptable, and yours — never deletes, modifies, or sends mail upstream.
Mail providers come and go. Your archive shouldn't. localmail keeps every byte you've ever received in a database you fully control.
Plain PostgreSQL. Plain files. Standard formats. Inspect, back up, export, or grep your mail any way you like — no proprietary blob, no lock-in.
localmail never deletes, modifies, or sends mail. The IMAP server is treated as the source of truth; the mirror is strictly downstream of it.
Lexical full-text plus vector embeddings, fused with reciprocal rank fusion. Searches message bodies and the text inside PDF, DOCX, XLSX, and 8 other attachment formats.
Mix Gmail (OAuth2), Microsoft 365, Fastmail, Proton Mail (via Bridge), iCloud, self-hosted, anything that speaks IMAP. Per-account sync threads, per-user access control.
Passwords and OAuth refresh tokens live in macOS Keychain or Linux Secret Service — never in a config file, never in the repository.
Attachments are stored by SHA-256 — the same PDF sent to ten different accounts lives on disk exactly once. Original filenames preserved per-message.
Three short steps in the user manual walk you through it, from a blank machine to a running archive:
localmail CLI with uv.# 1. Install uv (the Python package manager)
curl -LsSf https://astral.sh/uv/install.sh | sh
# 2. Install localmail globally
uv tool install --python 3.12 \
--from git+https://github.com/hherb/localmail \
localmail
# 3. Drop in a config & init the database
curl -fLo ~/.config/localmail/config.toml \
https://raw.githubusercontent.com/hherb/localmail/main/config.example.toml
localmail init-db
# 4. Add an account & sync
localmail add-account work-fastmail
localmail sync --account work-fastmail
Same archive, same hybrid search index, three front ends — each documented in the manual.
Real-time sync with IMAP IDLE on the INBOX and periodic poll on every other folder. systemd / launchd templates included. Survives network blips with exponential backoff.
Read about the daemon →One-shot sync, search with a rich DSL
(from:, has:attachment,
lang:, after:), status, failure recovery,
backfill workflows. Scriptable end-to-end.
Native Tauri 2 + Svelte 5 client. Connects to a local
localmail serve instance over HTTPS with
certificate pinning and per-user account ACLs.
No upload, no third-party indexer, no telemetry. Search runs locally against your own database. Embedding model downloads once and runs offline thereafter.