Sort your mail. Unsubscribe from the newsletters, clear out the rest, all on your own machine.
Français · Privacy · Connecting a mailbox · MIT
PurifyMail connects to your mailboxes over IMAP and puts every sender in one list, heaviest first. Each row offers the same three decisions:
- Unsubscribe and delete, for the newsletters, when a link exists.
- Delete, every message that sender ever sent you, for the volume no unsubscribe link can help with: the shop that mailed 300 order updates, the tool that notifies on every click, years of alerts from a service you left.
- Keep, and never be asked again, until you change your mind: pressing Keep on a sender you already kept puts them back in the list.
One list, both jobs. A checkbox narrows it to the senders that can actually be unsubscribed when that is what you are there for. There is no PurifyMail account, no server, and no telemetry: your mail is read on your computer and stays there.
- Connects to Gmail, Yahoo, Proton (via Bridge), Outlook, and any IMAP server. Several mailboxes at once, in one list, filterable per mailbox.
- Sorts one sender at a time when you want. A card view with three
full-size buttons and
123on the keyboard, for working through hundreds of senders without aiming at anything. - Scans the whole mailbox. Every folder, including the ones your rules fill, and on Gmail the All Mail view so archived newsletters are found too. Sent, Drafts and Trash are skipped, and your own address is never treated as a sender: what you wrote never appears in the list and can never be deleted from it.
- Rescans in seconds, not minutes. After the first pass, only messages the app has never seen are downloaded, and anything deleted elsewhere is noticed without re-reading the mailbox.
- Finds newsletters properly. Standard headers (
List-Unsubscribe,List-ID,Precedence), sending-platform fingerprints (Mailchimp, SendGrid, Brevo, Klaviyo, MailPoet, and a dozen more), address patterns, French and English wording, plus how often a sender writes to you. Missing a newsletter is treated as worse than flagging a sender you like, because one costs a click and the other stays invisible. - Reads the message when the headers say nothing. Plenty of small senders
declare no
List-Unsubscribeat all and bury the link in the footer: WordPress and MailPoet lists, self-hosted newsletters. PurifyMail opens a few recent messages and finds it, matching on the wording near the link rather than only inside it. - Unsubscribes properly. RFC 8058 one-click, then a plain request, then the confirmation page many senders answer with, whose form is filled in and submitted. When nothing works automatically, every link in the message is put in front of you, likeliest first, so no sender is ever a dead end.
- Groups a sender across its addresses.
bounce-9987@e.brand.comandnews@mail.brand.comland on the same row. - Keeps some, deletes the rest. Click a sender's name to see their messages one by one, tick the few worth keeping, and send the others to Trash. For the shop that sent 300 order updates and four invoices.
- Actually cleans up. Deleting a sender asks your server for every message from them, across every scanned folder, not just what the last scan cached. Unsubscribing deletes too, by default; switchable off.
- Never destroys anything. Deleting moves messages to your mailbox's Trash.
No
EXPUNGE, ever. - Works in the background. Decisions are queued and carried out while you keep sorting; unsubscribes run six at a time so a dead endpoint never holds up the queue.
- Asks for as little as possible. Your address picks your provider, the app password can be pasted with the spaces your provider printed, and a button opens the exact page that creates one. On a company server, Find it works the hostname out from your own domain.
- Speaks French and English, both written rather than translated.
Download the installer for your system from the Releases page.
| System | File |
|---|---|
| Windows | PurifyMail_x.y.z_x64-setup.exe |
| macOS | PurifyMail_x.y.z_universal.dmg |
| Linux | purifymail_x.y.z_amd64.AppImage or .deb |
The binaries are not code-signed. Signing is expensive, roughly €300 a year for a Windows certificate and $99 a year with Apple, and PurifyMail has no budget. Your system will therefore warn you the first time:
- Windows: "Windows protected your PC". Click More info, then Run anyway.
- macOS: "cannot be opened because the developer cannot be verified". Right-click the app, choose Open, then Open again in the dialog.
- Linux: make the AppImage executable with
chmod +x.
If that makes you uncomfortable, it should: build from source instead, the steps are just below.
Then open PurifyMail and follow Connecting a mailbox. The short version: Gmail, Yahoo, and Outlook need an app password, not your usual one, and Proton needs Proton Bridge running.
- Connect a mailbox. Pick your provider; the server settings fill in themselves. Press Test connection before saving: it tells you straight away whether the credentials work.
- Scan. The first scan reads every message header in the mailbox and then opens a few messages from the senders that declared no unsubscribe link, so a large account takes several minutes. It is done once: everything triage needs is kept locally, so sorting afterwards never waits on the network. You can stop it at any point; what was found is kept.
- Sort. Senders are listed by volume, heaviest first. Work through the
list, or switch to the one-by-one view and use
123on the keyboard. Tick several rows to act on them together. Decisions are carried out in the background, so you never wait on one to make the next. - Check your Trash if you deleted something and changed your mind.
You need Node.js 20+ and Rust, plus your platform's Tauri prerequisites.
git clone https://github.com/RDSV01/PurifyMail
cd purifymail
npm install
npm run app # run in development
npm run app:build # produce an installer in src-tauri/target/release/bundleSet VITE_DEMO=1 and the list fills with invented senders, so you can work on
the UI without connecting a real account. The seed command is a no-op in
release builds.
VITE_DEMO=1 npm run app # macOS / Linux
$env:VITE_DEMO="1"; npm run app # Windows PowerShellInstallers are not built by hand: GitHub Actions builds them for Windows, macOS, and Linux and attaches them to a release. A version tag starts it.
npm version 0.1.1 --no-git-tag-version
# put the same number in src-tauri/Cargo.toml and src-tauri/tauri.conf.json
git commit -am "release 0.1.1"
git tag v0.1.1
git push origin main --tagsThe release is created as a draft so a broken build never reaches anyone:
check the files, write the notes, press publish. To have it go out without
that step, set releaseDraft: false in
.github/workflows/release.yml. Expect about
fifteen minutes for all three platforms.
.github/workflows/ci.yml runs on every commit and does the fast checks:
frontend build (tsc is what stops fr.ts and en.ts drifting apart),
cargo fmt, clippy with no warnings tolerated, and the tests.
src/ React + TypeScript interface
i18n/ fr.ts and en.ts, peers rather than translations
state/store.ts Zustand store; all backend events land here
components/ List rows, the one-by-one card, bands, dialogs
views/ Senders, Mailboxes, Settings
src-tauri/src/
detect.rs Newsletter scoring, sender grouping, link extraction
mailbox.rs IMAP: connect, scan every folder, search, move to Trash
unsubscribe.rs One-click, plain request, confirmation form, mailto:
oauth.rs Gmail OAuth2 with PKCE on a loopback redirect
vault.rs AES-256-GCM credential store, key in the OS keychain
store.rs SQLite metadata cache
lib.rs Tauri commands, the scan worker, the action queue
Run the backend tests with cd src-tauri && cargo test. They cover the parts
worth getting right: sender grouping, unsubscribe-link extraction, header
unfolding, RFC 2047 decoding, mailto: parsing, confirmation-form detection,
and the detection threshold.
Issues and pull requests are welcome. Two things to know before you start:
- The detector is the product. If PurifyMail missed one of your newsletters, or could not unsubscribe you from one, that is a bug worth reporting: paste the message's headers and its footer HTML (with the addresses redacted) into an issue.
- No new network calls. Anything that contacts a host not already listed in PRIVACY.md will not be merged.
MIT. See LICENSE.