Skip to content

Latest commit

 

History

History
310 lines (242 loc) · 17 KB

README.md

File metadata and controls

310 lines (242 loc) · 17 KB

Mailbox — the modern, open source email client

Mailbox

An email client for everyone.

Website: codingncaffeine.github.io/Mailbox

Mail, Calendar, People, Tasks, Notes, Journal, Feeds and Weather in one desktop application for Linux. Open protocols only — IMAP, POP3, SMTP, CalDAV, CardDAV — with no cloud service behind it, no account required, no AI features and no telemetry.

Status: it does the whole job now, not just the mail. Add an account and mail works end to end over IMAP, POP3 and SMTP against a local SQLite store — with full-text search, client-side rules that compile to Sieve, a junk filter that learns from your own marks, and S/MIME and OpenPGP in both directions. Calendar, People, Tasks, Notes, Journal and Feeds are whole modules against that same store rather than placeholders, and the Add Account window also takes a CalDAV or CardDAV server: it finds the calendars and address books on offer and keeps the ones you pick in sync on every send/receive.

Microsoft accounts (outlook.com, hotmail.com, live.com) and work or school addresses on Microsoft 365 sign in through your browser with nothing to register; Mailbox 0.6.5 and earlier asked you to register a client application of your own, and the next release does not. Proton Mail is reached through Proton Mail Bridge, running on the same machine. Gmail, Yahoo and AOL want an app password rather than your ordinary one, and Gmail additionally wants two-step verification on and IMAP switched on in its own settings — the wizard says so, with the link, when it recognises the address. An address on a domain of your own is recognised by who handles its mail, so one hosted by Microsoft 365, Google Workspace, Fastmail or Proton gets that provider's settings. Servers that speak plain IMAP and SMTP, self-hosted ones included, just take a password.

The Mailbox shell: folder pane, message list and reading pane

Weather has been added

New in 0.6.5: a Weather module on the rail. Keep places by city or zip code and see each one's conditions now, the next two days hour by hour and two weeks ahead; the National Weather Service's warnings and forecasters' discussion in the United States; air quality; and a map with radar, satellite, temperature, wind, precipitation and clouds, played through time. The calendar shows the next three days beside the date. No account and no key: every copy asks the free services itself.

mailbox.weather.webm

What it is

A dense, keyboard-driven, offline-first mail client for people who want a real desktop application rather than a web page in a window.

  • Everything is local. Your mail lives in a store on your machine and stays readable when the network does not. Nothing is uploaded to us — there is no service behind this to upload it to, and the one thing that would call home, the update check, is off unless you turn it on.
  • Open protocols. POP3 and IMAP for mail, SMTP for sending, CalDAV and CardDAV for calendars, contacts, tasks and notes. Works with self-hosted servers and any provider that speaks them.
  • Deeply customizable. Every action is a named command, the toolbar is a rearrangeable document, and the theme system reaches every surface in the application — not just a palette swap.
  • No lock-in. GPL-3.0, and your data stays in formats you can take elsewhere.

Features

Mail. IMAP, POP3 and SMTP with autoconfig and OAuth2; mail is checked when the application opens and every thirty minutes after, on a schedule you can change; a rolling offline window per folder, or everything. Full-text search (FTS5) with a keyword grammar (from:, subject:, dates), search folders, and All Mailboxes. Conversations with eleven arrangements, Focused Inbox, an opt-in unified inbox. Rules run client-side, and compile to Sieve for servers that speak ManageSieve, so they keep working while your machine is off. A Bayesian junk filter trained on your own marks, with safe- and blocked-sender lists that always win. Snooze, Undo Send, schedule send, Archive, Ignore Conversation, Quick Steps, Conversation Clean Up. Signatures per account for new mail and replies, five quoting styles, and a rich text editor with autocorrect and spell checking built for this application.

Reading without being read. Every message passes a sanitizer before the rendering engine ever sees it; remote images are blocked by default and a report names the hosts that wanted to be fetched. DKIM, SPF and DMARC results are shown on the message, with warnings for lookalike domains and display-name spoofing. S/MIME and OpenPGP are built in both directions — signing, encryption, protected headers, key generation, WKD lookup — and ship disabled, so nothing cryptographic happens until you ask.

Calendar. Recurring events with real time-zone and DST handling, a second time-zone column, iMIP invitations (send, receive, answer), reminders, a scheduling assistant, and read-only .ics subscriptions. People: vCard address books, read-only LDAP directories, autocomplete, Select Names, business-card and list views, categories shared across every module. Tasks: the To-Do List, task folders, recurring chores that regenerate on completion, reminders, and Google Tasks sync. Notes and Journal: a notes wall and a six-view journal timeline. Feeds: a built-in RSS/Atom reader as a module of its own, with its own store. Weather: forecasts, warnings, air quality and a weather map for the places you keep, and the next three days on the calendar.

Import and export. Maildir in three layouts, mbox, .eml, .msg, read-only .pst archives, and whole Thunderbird profiles including translated filters. Export is byte-exact: every message is kept as the RFC 822 bytes it arrived as, so mbox and .eml leave with nothing lost, plus .ics and .vcf for the other modules.

A desktop citizen. Desktop notifications with Reply, Delete and Mark Read actions; a tray icon with an unread badge; autostart and start-minimised; mailto: handling and single-instance activation; MIME associations; printing through the engine's own dialog, Print List, and Print to PDF. Passwords live in the desktop keyring (Secret Service) — never in a file. Everything stores under the XDG directories. AutoArchive, Mailbox Cleanup, Recover Deleted Items and store compaction keep the mailbox in hand.

Yours to shape. Four complete themes with a live editor and hot reload; three toolbar modes with a rearrangeable layout and KeyTips; every action a named, rebindable command with conflict detection; adjustable density; HiDPI including fractional scaling; a plugin host with a versioned API, manifest permissions, and enable/disable without a restart.


Building

Requires the .NET 10 SDK.

dotnet build
dotnet test
dotnet run --project src/Mailbox.App

Packaging

One script publishes a self-contained build and packs it three ways: a tarball that runs from wherever it is extracted, a .deb for Debian 13 and its relatives, and an .rpm for Fedora and its relatives. packaging/aur/PKGBUILD repackages the tarball for Arch. Both x86_64 and aarch64 are built from the same script — cross-publishing is a second run of it, since the runtime and every native library come out of the NuGet runtime pack for the target.

bash packaging/build-release.sh          # x86_64: tarball, Mailbox.deb, Mailbox.rpm
bash packaging/build-release.sh arm64    # aarch64: tarball, Mailbox-arm64.deb, Mailbox-aarch64.rpm
bash packaging/build-release.sh musl     # x86_64 against musl: tarball
bash packaging/build-release.sh all      # every one

bash packaging/test-deb.sh          # installs the .deb in a clean debian:trixie container (podman) and probes it
bash packaging/test-rpm.sh          # the same in a clean fedora:42 container
bash packaging/test-musl.sh         # unpacks the musl tarball in a clean alpine container, probes it, captures the window
bash packaging/build-alpine.sh      # builds the tree from source on alpine with its own SDK, runs the suite, captures the window

The tests are part of every build: the system libraries the bundled Chromium links against, the keyring tool and the notification tool are exactly the dependencies that are present on a development machine and missing on a clean one. They pass when the install resolves, no bundled library wants anything the package did not bring, and the binary gets as far as looking for a display. rpmbuild is borrowed from a container where the build machine has none, which is the ordinary case on Arch.

Runtime dependencies on the target: X11 or Wayland, fontconfig, ICU; the libraries the bundled Chromium links against (NSS, ATK, CUPS, Pango, ALSA and a few X extensions — the packages declare them); and, recommended, secret-tool (libsecret) for the keyring, notify-send (libnotify) for notifications, Hunspell dictionaries for spelling, a desktop portal (with GTK 3 as the fallback) for the file dialogs, and the metric-compatible fonts below.

The reading pane is Chromium, shipped inside Mailbox (in chromium/ beside the binary), so a system update cannot change or break it. It runs with Chromium's sandbox on, JavaScript off, and the network closed to everything but the message being shown. The sandbox needs a user namespace for Chromium's helper; on Ubuntu 23.10 and later the .deb installs the AppArmor profile that allows one. Where no sandbox can be had — the tarball on a restricted Ubuntu, for instance — Mailbox does not run Chromium unsandboxed: it renders each message as text and says why in its log. MAILBOX_NO_CHROMIUM=1 asks for text deliberately.

Alpine and other musl systems

Mailbox builds from source against the musl C library with the distribution's own SDK — on Alpine, apk add dotnet10-sdk tzdata and then the three commands above — and every release carries a linux-musl-x64 tarball published the same way as the others. A musl build has no Chromium, which is built for glibc, so its reading pane renders each message as text; everything else is the same. To run it, Alpine needs:

apk add icu-libs tzdata libstdc++ fontconfig font-dejavu libx11 libice libsm libxext libxi libxrandr \
        libxcursor libxkbcommon mesa-egl libsecret libnotify

CI builds and tests every change on alpine:latest beside Ubuntu, and packaging/build-alpine.sh does the same in a container here, ending with a capture of the window drawn on musl.

Fonts

Mailbox renders received mail at the metrics the sender intended by substituting metric-compatible typefaces. Install these so common business fonts lay out correctly:

# Arch
sudo pacman -S --needed ttf-carlito ttf-caladea ttf-liberation gsfonts

# Debian / Ubuntu
sudo apt install fonts-crosextra-carlito fonts-crosextra-caladea \
                 fonts-liberation2 fonts-urw-base35

Proprietary fonts are detected and preferred when you already have them installed. They are never shipped, because they are not redistributable.

Environment variables

For testing, for scripted captures, and for overriding a platform quirk without opening Options.

Variable Values Purpose
MAILBOX_THEME colorful, white, darkgray, black Startup theme
MAILBOX_DENSITY compact, cozy, comfortable Row spacing
MAILBOX_LAYOUT classic, modern Which shell layout to use
MAILBOX_RIBBON simplified, classic, collapsed Toolbar display mode
MAILBOX_TEXT_MODE subpixel, antialias, alias Glyph rasterization
MAILBOX_TEXT_HINTING none, light, strong Hinting strength
MAILBOX_CAPTURE a .png path Render the window once and exit
MAILBOX_WAYLAND 1 Run on the native Wayland backend instead of X11 (through XWayland on a Wayland session). Experimental; the log says which backend came up
MAILBOX_LOG_LEVEL debug, info, warning, error Log verbosity

Logs are written to $XDG_STATE_HOME/mailbox/logs, five runs kept.


Themes

The four themes are complete token sets, and any of them can be the base of one of your own. A theme is a JSON file in ~/.config/mailbox/themes/ — an id, a name, the theme it starts from, and the tokens it changes, as few as it likes: three palette entries over black are a whole theme, because everything the base derives from them follows. Edits show while Mailbox is running; the theme picker in Options › General lists your files after the built-ins.

mailbox --export-theme darkgray my-theme.mailbox-theme.json   # a complete theme to start from

assets/themes/ holds the four built-ins in that form, as the documentation of every token.

Layout

src/Mailbox.Core             domain model, command catalogue, toolbar layout, settings, logging
src/Mailbox.Theming          token system, themes, font substitution, icons
src/Mailbox.Controls.*       the toolbar, calendar, people, tasks, notes and journal controls
src/Mailbox.Store            SQLite store, migrations, search index, backup and restore
src/Mailbox.Protocols        IMAP, POP3, SMTP, autoconfig, OAuth, feeds, credentials
src/Mailbox.Dav              CalDAV and CardDAV sync
src/Mailbox.Scheduling       iCalendar, recurrence, time zones, invitations
src/Mailbox.Contacts         vCard, the address book, LDAP directories and name parsing
src/Mailbox.Editor           the rich text editor and its HTML
src/Mailbox.Rendering        the sanitizer and the offscreen engine the reading pane draws with
src/Mailbox.Security         S/MIME and OpenPGP
src/Mailbox.Import           Maildir, mbox, .eml, .msg and Thunderbird profiles
src/Mailbox.Pst              the read-only archive-file reader
src/Mailbox.Junk             the junk classifier
src/Mailbox.Google           Google Tasks
src/Mailbox.Plugins[.Api]    the plugin host and the API plugins compile against
src/Mailbox.App              the Avalonia shell: every module, Options, the dialogs
tests/Mailbox.Tests          the test suite, no UI thread required
tools/generate-icons.py      regenerates the icon glyph map
assets/                      bundled fonts, the icon ladder and the reminder sound
packaging/                   desktop entry, MIME associations, icon install, the release build and its dependency test
assets/themes/               the four built-in themes as theme files (generated: tools/export-themes.sh)

Several components are written from scratch rather than taken off the shelf, because no GPL-3-compatible option exists: the toolbar, the message list, the rich text editor, the calendar views, the DAV sync engine, the theme engine, the archive-file reader, the junk filter and the plugin host.


Design notes

Subpixel antialiasing works on Linux. Widely reported not to, and it is most of what makes an application feel wrong before you can say why. Mailbox asks for SubpixelAntialias with strong hinting and, where the stack honours it, gets the coloured glyph fringing Windows draws rather than the thinner grayscale one. Where it does not — the reports upstream are real for someone, and look to be compositor, driver or fontconfig specific — MAILBOX_TEXT_MODE and MAILBOX_TEXT_HINTING override both, and the startup log names the mode that came up.

Themes cover every surface. Four built-in themes, each authored as a complete explicit token set rather than derived from one another, with a coverage gate that refuses to load a theme missing any token. The usual failure of themeable applications is holes — a compose window or a settings page the theme cannot reach — so every surface takes its colour from a named token rather than a literal, and the gate makes a missing one loud.

Fonts resolve honestly. The substitution table separates metric-compatible pairs from lookalikes, and a fallback can never inherit a metric claim it has not earned. Outgoing mail names the original font first, so recipients who have it see it, while local rendering uses the substitute at identical metrics and the layout matches either way.

The toolbar is data, not markup. It renders a layout document, which is what makes it rearrangeable and lets plugin commands be placed through the same path as built-in ones.


Security and hardening

Mail is untrusted input, and this application treats it that way: an unbypassable sanitizer in front of the rendering engine, remote content blocked by default, credentials in the desktop keyring only, no telemetry, and the packaged launcher confining the whole application in a hardened transient systemd user unit — read-only outside its own data directories, no new privileges, an empty capability set, and a syscall allow-list, with every deliberate exception documented beside the property it relaxes (packaging/mailbox-launcher.sh).

The wiki's Hardening page walks through each layer with pointers into the code and checks you can run yourself.


Licence

GPL-3.0-or-later. See LICENSE.

Not affiliated with or endorsed by any other software vendor.