Turn saved email archives into PDFs you can read, share, and keep.
MailboxPDF helps you take a saved email archive and turn it into a clean PDF. It is designed to feel safe and predictable: it works on your own machine, it does not pull in content from the internet, and the same main choices are available in the desktop app, the command-line tool, and the web app.
- Open saved email archives such as
.mboxfiles. - Save one PDF, one PDF per email, or one PDF per conversation.
- Check the result before saving it, including the file names MailboxPDF plans to use.
- Start with built-in presets instead of setting everything by hand.
- Keep plain-text email, formatted email, pictures, attached PDFs, and common office files such as Word and spreadsheet documents together in one export.
- Keep your mail on your own machine while it is opened, previewed, and turned into PDFs, with no internet connection required.
- Use it on Linux, macOS, Windows, and on the web.
- Choose from English, Slovenian, German, French, Macedonian, Russian, Japanese, Swedish, Spanish, Portuguese (Brazil), Italian, Dutch, Polish, Simplified Chinese, and Korean.
If you want the simplest path, start with the desktop app or the web app.
Download the latest desktop app that matches your computer:
- Windows: MailboxPDF for Windows
- macOS: MailboxPDF for macOS
- Linux: MailboxPDF for Linux
Typical flow:
- Open or drag in a saved mailbox file such as an
.mboxfile. - Pick a preset or change the export options.
- Check the preview and the file names it will save.
- Save the PDFs.
If you do not want to install anything, use the hosted web app:
Open MailboxPDF in your browser
The web app uses normal file picking, drag and drop, and browser downloads.
If you prefer a terminal, downloadable CLI builds are available for:
- Windows: MailboxPDF CLI for Windows
- macOS: MailboxPDF CLI for macOS
- Linux: MailboxPDF CLI for Linux
You can also run the command-line tool directly from this repository.
Preview a mailbox without saving files:
cargo run -p mbox-pdf-cli -- inbox.mboxSave one PDF:
cargo run -p mbox-pdf-cli -- inbox.mbox \
--write \
--output-dir outSave one PDF per conversation with a preset:
cargo run -p mbox-pdf-cli -- inbox.mbox \
--write \
--output-dir out \
--preset thread-digestShow the built-in presets:
cargo run -p mbox-pdf-cli -- --list-presetsCommand-line notes:
- Without
--write, MailboxPDF only shows you what it plans to save. --preset thread-digestis a good starting point if you want one PDF per conversation.
cargo run -p mbox-pdf-cli -- inbox.mbox \
--write \
--output-dir out \
--export-mode singlecargo run -p mbox-pdf-cli -- inbox.mbox \
--write \
--output-dir out \
--export-mode per-messagecargo run -p mbox-pdf-cli -- inbox.mbox \
--write \
--output-dir out \
--preset thread-digestcargo run -p mbox-pdf-cli -- inbox.mbox \
--write \
--output-dir out \
--preset compact-review- Conversation grouping depends on the reply information saved in the emails themselves, so messy archives can still group imperfectly.
- Hiding long quoted replies is intentionally cautious.
- Formatted emails may not look exactly the same as they did in the original mail app.
- The preview is close to the final result, but complex email layouts and attached PDFs can still look slightly different after export.
- In the web app, saving one PDF per email or conversation can trigger several download prompts.
- Very large mailboxes or mailboxes with many attachments can take noticeable time and memory.
MailboxPDF is a Rust workspace with three crates:
crates/corefor shared parsing, preview, planning, rendering, and PDF exportcrates/clifor the command-line interfacecrates/guifor the native and browser-based GUI
The static project site is rendered by xtask from shared Rust page templates plus site-specific .po catalogs under site/locales/. The app UI continues to use .po catalogs under crates/core/locales/.
Common development commands:
make validateruns formatting checks, linting, tests, and check-only validationmake buildbuilds native, wasm, and packaged web outputsmake gh-pagesbuilds the GitHub Pages bundle undertarget/gh-pages/and prepares the local publish branchcargo run -p xtask -- gh-pages-minify target/gh-pagesruns the Pages bundle minifier directlycargo run -p xtask -- gh-pages-prepareprepares the local Pages worktree and single-commit branch directlycargo run -p xtask -- serve-gh-pages target/gh-pagesserves the staged Pages bundle locallymake serve-webbuilds and serves the local GitHub Pages site fromtarget/gh-pages/make test-visualruns visual regression testsmake benchmarkruns the benchmark harness
Planning and implementation tracking live in PLAN.md and IMPLEMENTATION_CHECKLIST.md.
To prepare and locally commit a project site for a gh-pages branch without maintaining a custom GitHub Actions build workflow:
make gh-pagesThat command:
- stages a deployable static site under
target/gh-pages/ - minifies the staged HTML, inline CSS/JS, generated JavaScript, and strips removable WebAssembly custom sections for a smaller Pages bundle
- syncs a dedicated local worktree at
.worktrees/gh-pages/ - rebuilds
gh-pagesas a single-commit local branch for force-push-based publishing
The staged site has this shape:
target/gh-pages/index.htmlfor the project landing pagetarget/gh-pages/app/for the WebAssembly GUI bundletarget/gh-pages/.nojekyllso GitHub Pages serves the files directly
The intended branch-publish flow is:
- Run
make gh-pages. - Review the prepared branch in
.worktrees/gh-pages/if you want. - Push
gh-pageswith force when you are ready.
make gh-pages refuses to overwrite uncommitted changes in .worktrees/gh-pages/, so manual edits on that branch stay protected until you commit or clean them yourself. Each successful run then rewrites the branch back down to one fresh publish commit.
That keeps the public project URL available for a landing page while the browser app lives at /app/.
For a local preview of the built Pages site, run make serve-web. The server listens on http://127.0.0.1:8080/ by default, and you can override the port with SERVE_WEB_PORT=<port>.
MailboxPDF is licensed under the GNU Affero General Public License v3.0 only. See LICENSE.