mboxShell 1.0: The First Stable Release, and Everything Since 0.8
mboxShell, our open-source terminal tool for MBOX files, reaches 1.0 with a config file that finally does what it says. Here is that, plus what came in the four releases we never wrote about: Maildir export, a security review, a light theme, Aruba mailboxes and numbered exports.
mboxShell, the free, MIT-licensed terminal tool that Mbox Viewer grew out of, reached 1.0.0 today. It is the first stable release, and the number means something concrete: from here on the command line and the config file follow Semantic Versioning, so anything that would break a script you wrote against them can only arrive in a 2.0.
We last wrote about it in August, when 0.7.2 learned to cut a mailbox into smaller ones. Six releases have gone out since. One of them, 0.7.3, only updated a link; the other five never got a post here. This one catches up.
1.0: the config file does what it says
The honest headline of 1.0 is a bug fix. mboxShell has always read a config.toml, and the README documented a long list of options for it — but only four were actually read: the log level, the theme and the two attachment options. default_sort, sort_order, date_format, layout, show_sidebar, csv_separator, cache_dir and the rest were accepted and then ignored. They all work now. A few that never had anything behind them ([columns], [performance], default_format…) are gone; an old file that still has them loads without complaint.
To make the file easy to find, there is a new config command:
$ mboxshell config path
/Users/you/Library/Application Support/mboxshell/config.toml
(not created yet: `mboxshell config defaults` prints a starting point)
config defaults prints every option with its default and a comment, so mboxshell config defaults > "$(mboxshell config path)" gives you a file to start editing. config show prints the one you have and flags what it will ignore:
$ mboxshell config show
[general]
date_format = "%d/%m/%Y %H:%M"
sort_order = "upward"
Invalid value for general.sort_order: "upward"; using the default
Before 1.0, that value was dropped in silence — and a malformed date_format crashed the interface. Now each bad value falls back to its default with a warning. One correction in the docs, too: on macOS the file lives in ~/Library/Application Support/mboxshell/, not ~/.config/mboxshell/ as the README claimed.
0.8.0: a full review of the tool
The largest of the releases we skipped came out of reading the whole tool from end to end with one question: what happens when the mailbox is hostile, broken or simply huge?
Security. The HTML sanitizer — the only thing between a hostile email and your browser when you export to HTML or press H — was updated to close two published XSS vulnerabilities, and CI now audits dependencies on every build. Remote images are blocked by default in HTML exports, because opening the page would fetch them and a tracking pixel tells the sender when and from where the archive was read; the page says how many were blocked, and --allow-remote-images brings them back. And the index, the CSV and the temporary files are now created fresh and renamed into place, so a mailbox shipped with a planted symlink next to it can no longer get a file of yours overwritten.
Merge. Deduplication used to treat two messages as the same as soon as they shared a Message-ID. That meant a message planted earlier in the inputs could make a legitimate one vanish from the merged archive. A message is now a duplicate only when its Message-ID and its content match. Merging also streams its inputs instead of reading each one whole into memory.
Bad input fails loudly. A search filter it could not read — after:2099-13-45, size:big — used to be dropped, so the search returned everything, and an export --query built on it exported the whole mailbox. It is now an error. A file that is not a mailbox at all is rejected instead of opening as “0 messages”, and an 800 MB mailbox without line breaks now indexes in about 20 MB of RAM instead of 816.
Accessibility. The theme setting finally works: light is new, with every text colour at WCAG AA contrast or better, and terminal uses no colours of its own, so it follows your terminal’s palette (NO_COLOR forces it). The selected message is marked with > and the active filter with •, so neither depends on colour. And the terminal’s real cursor now follows the focus, which is what screen readers, braille displays and magnifiers track.
Maildir export. export --format maildir writes a standard cur/ new/ tmp/ folder, works with --query, and turns read and starred marks — including Gmail’s Opened and Starred labels — into Maildir flags:
$ mboxshell export INBOX --format maildir --output ./INBOX-maildir
Exporting 2 message(s) (maildir) → ./INBOX-maildir
Exported to Maildir ./INBOX-maildir (2 message(s))
That makes the list of formats mboxShell writes MBOX, Maildir, EML, CSV, TXT and HTML.
0.8.1 and 0.8.2: small fixes that came from GitHub
Mailboxes from Aruba’s webmail opened as a single message. Aruba writes the line that separates messages with a modern date format instead of the classic one, and mboxShell only recognised the classic one. Both are accepted now — strictly enough that a line of body text quoting a date still does not split a message in two.
Numbered folders and files. attachments --dirname seq-no names each message’s folder after its position in the mailbox — 0007/ — instead of its date and subject, which time zones and truncated subjects made hard to match back to the message. The number is the same index that search --json reports. stats now also counts messages without a Message-ID: when that is 0 and there are no duplicates, the Message-ID is a safe unique key for that mailbox.
HTML exports ready to become one PDF. Each exported page starts with a hidden heading and an invisible marker. Converted with wkhtmltopdf and joined into a single PDF, each email gets its own bookmark, and the marker shows where to split it again.
0.8.2 is one fix: exporting could crash on a message whose subject or sender had an accented letter near the start. The check for reserved Windows file names (CON, NUL…) added in 0.8.0 cut the name at a fixed byte, which can fall in the middle of an é. It affected every platform, not only Windows.
0.9.0: exports that line up with their attachments
export now takes the same --dirname seq-no option, so 0007.html and the folder 0007/ holding its attachments belong to the same message. The numbering is computed over the whole mailbox even when --query selects only part of it, so export and attachments always agree.
It also fixes the first message of a mailbox that begins with a UTF-8 byte order mark (BOM). That message was exported with the separator line mistaken for a header, so it lost its subject and was saved as unknown_unknown.
What has not changed
mboxShell still opens mailboxes of any size, still never writes to the file it reads, and still runs entirely offline. The mboxShell page has the pre-built binaries for Linux, macOS, FreeBSD and Windows, the commands and the release notes; the full history is in the repository’s changelog on GitHub.
And if you would rather click than type, the same idea lives in Mbox Viewer for Mac and Windows, free for mailboxes up to 1 GB.
Open your archive with Mbox Viewer
Native Mac and Windows app. Streams MBOX and EML files of any size, fully offline.