How the pieces fit together

The desktop app does not talk to Postgres directly. It talks HTTPS to a localmail serve process that you run locally (or on a LAN host). That gives you:

┌─────────────┐ HTTPS ┌─────────────────┐  pg  ┌─────────┐
│ Desktop app │ ─────► │ localmail serve │ ───► │ Postgres│
└─────────────┘        └─────────────────┘      └─────────┘
                              ▲
                              │ same DB, separately
                              │
                       ┌──────┴──────┐
                       │ localmail   │  IMAP IDLE / poll
                       │ run (daemon)│  ────► your mail providers
                       └─────────────┘

Set up the server

  1. Generate a TLS cert.

    The server speaks HTTPS by default. For localhost / LAN use a self-signed cert is fine — the app supports a trust-on-first-use pinning flow.

    localmail rotate-tls \
      --cert ~/.config/localmail/tls.crt \
      --key  ~/.config/localmail/tls.key
    Localhost-only?

    If you'll only ever connect from the same machine, you can run with --no-tls --bind 127.0.0.1 and skip the cert step. TLS is refused for any non-loopback bind without a cert.

  2. Create an API user.

    The desktop app authenticates with a username + password (which the server stores as an argon2id hash). The password is yours to pick; there's no link to your IMAP credentials.

    localmail add-api-user alice
  3. Grant the user access to one or more accounts.

    By default, a new API user has access to no accounts and every API call returns empty lists. You explicitly grant access per (user, account) pair:

    localmail grant-account alice horst-gmail
    localmail grant-account alice work-fastmail
    localmail list-api-users --with-grants
  4. Start the server.

    localmail serve \
      --bind 127.0.0.1 --port 8443 \
      --tls-cert ~/.config/localmail/tls.crt \
      --tls-key  ~/.config/localmail/tls.key

    For an always-on setup, wrap this in a systemd / launchd unit the same way you did the daemon — see the Daemon page for templates. The two processes are independent: localmail run mirrors mail; localmail serve serves it.

Install and run the desktop app

Pre-built bundles are produced from the gui/ directory of the repository. Until the project ships signed installers, the quickest path is to build from source.

Build prerequisites

PlatformWhat you need
macOS Xcode command-line tools (xcode-select --install); WebView ships with the system.
Linux sudo apt install libwebkit2gtk-4.1-dev build-essential curl wget file libssl-dev libayatana-appindicator3-dev librsvg2-dev (Debian/Ubuntu) or distro equivalents.
Windows WebView2 (pre-installed on Windows 11; runtime installer on older).
All Node.js 20+, npm, Rust 1.80+ via rustup.

Build & run

git clone https://github.com/hherb/localmail
cd localmail/gui
npm install
npm run tauri dev          # development window with hot reload

# Or build a release bundle:
npm run tauri build
# Output in src-tauri/target/release/bundle/

First-run flow inside the app

  1. Connect.

    The app opens to a Connect screen pre-filled with https://localhost:8443. Adjust if your server is elsewhere, then click Connect.

  2. Trust the certificate (once).

    For a self-signed cert, the app shows you the SHA-256 fingerprint of the cert it just saw. Compare it with the fingerprint localmail rotate-tls printed, then click Trust this certificate. The app pins it; future connects don't ask again unless the cert changes.

    Fingerprint mismatch

    If you ever see the trust dialog when you weren't expecting it, the cert changed. Either you regenerated it (fine — re-trust), or someone has interposed themselves between the app and the server. Verify out-of-band before clicking trust.

  3. Sign in.

    Enter the username and password you set with add-api-user. The app gets back a bearer token, stores it locally, and uses it on every subsequent request.

  4. Browse and search.

    The header shows the accounts you've been granted access to. The search bar talks to the same hybrid retriever the localmail search CLI uses, with the same DSL — operators, dates, languages, attachments.

What the app can do today

What the app does not do

Connecting from another machine

For phone, tablet, or another laptop on your LAN:

  1. Re-issue the TLS cert with a hostname covering the other machine — localmail rotate-tls --cert … --key … --hostname localmail.local --force.
  2. Run localmail serve bound to a reachable address — --bind 0.0.0.0, or a Tailscale / WireGuard IP.
  3. From the client device, point the app at https://localmail.local:8443 and trust the new fingerprint.
Mobile

There's no native mobile app yet. The HTTPS API is documented and stable, so a third-party client is possible. Watch the project repository for updates.