New features, improvements, and fixes in every release.
v2.20.0October 13, 2026Latest
Added
Join Discord from Help. Settings, Help now has a Join Discord button beside Report Bug, matching the sidebar and the report dialog.
Folders get icons in color. Every folder icon in the sidebar now has a color by kind (Inbox, Sent, Drafts, Trash and so on, plain folders and folders kept on this computer too). Right-click any folder to give it a color of your own, or reset it. To make every folder icon one color that follows the theme, choose Theme color under Settings, Appearance, Folder icons.
Contacts: a built-in address book. Open Contacts in the sidebar for one card per person, built from your own mail plus what you add: how many emails you received from, sent to and copied them, the full correspondence with each contact by date, suggestions that say why they were made, a review queue for addresses found in your mail, merge with a preview that you can undo, and vCard import and export. A copy of your contacts is kept in your vault and is included in backups and in an account transfer. Contacts stay on this computer and are not synced with any provider.
A Teal color palette, to go with the teal app icon. Pick it in Settings, Appearance, Colors, beside Indigo and Graphite, in light or dark. Dark gets teal-tinted ink and light gets cream paper, and controls, Insights charts and chat bubbles follow the accent. Graphite stays the default for new installs and your saved choice is not touched.
A code sent to you by email is one click from the clipboard. When a verification code, one-time passcode or PIN lands in your inbox, a small bubble in the top-right corner, where minimized drafts sit, shows the code and who sent it, with Copy and Copy & delete. Copy & delete puts the code on the clipboard and moves the email to Trash with the usual undo. Click the bubble to open the email, or its x to dismiss it; it leaves on its own after ten minutes. A code in the subject is read at once; a subject that only announces one ("Sign in to Acme") has its body read for it. Order numbers, phone numbers, amounts, dates and promo codes are not offered.
JMAP accounts. Add an account on a JMAP server. Sign in with a password or an API token (on Fastmail, that is an API token you create in its settings), and the server is found from your address when your server publishes it (Fastmail is built in); otherwise enter its address. A server outside your own domain (other than Fastmail's) asks you to confirm it before your password or token goes to it. New mail arrives through push, with polling as a fallback, and sending uses your server's identities, so send-as aliases come straight from the server.
Store your vault in JMAP format. Each message keeps its original bytes plus a standard JMAP JSON record, and identical messages in several folders are stored once. Convert either way at any time in Settings > Storage, keeping the old files aside or deleting them after each message is verified. Conversion runs in the background and picks up where it left off after a restart.
Go to mailbox, from any search result or All Inboxes row. Right-click an email found by a search, or listed in All Inboxes, and choose Go to mailbox: the search closes, its own account and folder open, and the email opens in its full conversation with that message expanded and scrolled to. It is added to your existing right-click menu once; remove it in Settings, Quick actions if you don't want it.
Search results and All Inboxes rows show which account each email is in. The account's colored initial, as in the sidebar, sits before the sender, and pointing at a row lights that account in the sidebar. Search results from All Inboxes had no account marker before.
Open or save a picture in an email. Double-click a picture in the body of an email to open it in Preview on a Mac, or in your default image viewer on Windows and Linux. In the reading pane, right-click it for Open in Preview (Open Image on Windows and Linux) and Save As. This works for pictures sent inside the email; a picture loaded from the web is left alone, and an SVG drawing can be saved but is not opened.
Fixed
Saved views open fast, and show they are loading. Opening a view such as one filtered by sender could take ten seconds with many accounts, while the list still showed the folder you came from under the view's name, with that folder's count and dates. The list now shows placeholder rows until the view's mail arrives. The view's mail is read in one pass over all your accounts instead of one pass per account. The counts beside your views are worked out one at a time and no longer hold up the view you open.
Deleting an Outlook email that Outlook already removed works. A note to yourself, or any message deleted elsewhere, failed with "Graph delete_message failed (404)" and could not be deleted; it now leaves like any other delete.
Notes to Self drops notes the server no longer has. A note MailVault deleted, or one a check found in no folder on the server, leaves the board (your vault copy stays, and search still finds it). The open board also lists again by itself after a sync, so a new note shows up without pressing Refresh.
An old forward no longer joins a new email with the same subject. A "Fw:" or "Re:" email without reply headers was put into any conversation with the same subject, so a forward from two years ago opened as the first message of a new, unrelated email. Such a message now joins a conversation only when it has a message within 30 days of it, and the nearest one when there are several.
A phrase in the search box stays one tag. Typing project re 1 and pressing Enter now adds one tag instead of three, so each Enter adds one search term. Operators (from:ann), exclusions (-word), quoted runs and || / && still become tags of their own.
Reply and Reply all on mail you sent. Open an email from Sent, in search results or in a folder, and the reading pane now offers Reply and Reply all (Reply all only when there is more than one person to reach). Both write to the people you sent it to, never to yourself.
Pictures in an email keep their shape. A screenshot pasted into an email from Outlook, such as a Power BI report, was squashed sideways to fit the reading pane. It now shrinks to fit at its own proportions, in the reading pane, chat view and exports.
Delete everywhere removes an inbox email from the server too. On a message in the inbox it only moved the server copy to Trash, so the email was still on your server while the copies on this computer and in the backup went. It now deletes the server copy for good, like it already did in every other folder.
Delete everywhere in the reader works on an email not yet in your vault. On a message only the server held ("On the server, not saved to your vault yet") the button did nothing, and in the full-size reader and the chat view it was missing. It now asks to delete it from the server for good, which is everywhere it is. On a message your vault holds, opened from the Server view, the confirmation now names the vault copy too.
An update that failed to install finishes after a restart. On a Mac, the first update attempt after installing MailVault from a download could end with "An error occurred while running the updater": macOS refused Sparkle's installer its cache folder on the app's first run, so nothing was installed until MailVault was quit and reopened. MailVault now says what happened and offers Restart and install; after the restart the update, already downloaded, is offered ready to install.
Delete everywhere says why it removed nothing. From the reader, the row menu, the selection bar and the chat view, a purge that was refused by the server, or held back because the folder's UIDVALIDITY could not be trusted, showed no message and the mail simply came back. It now raises the same warning the list shows, with how many were removed and how many were not.
v2.19.2October 10, 2026
Added
The unread filter tells you when a folder cannot have unread mail. Turn Unread on in Sent, Trash or any folder other than the inbox and that folder flashes in the sidebar: mail there was sent or filed, never received, so the empty list is right and the account's unread badge counts the inbox only.
Send asks when you mention an attachment but forgot it (Premium). A message that says "attached", "see the attachment", "im Anhang", "ci-joint", "ๆทปไป" and the like in any of the app's languages, with no file attached, stops at Send and offers Attach file or Send anyway. Quoted text and your signature are not read, nor is a reply's subject. Turn it off in Settings > Mail preferences > Behavior > Attachments.
Get reminded when nobody replies (Premium). When you write an email, the bell next to Templates offers to remind you in 1 day, 3 days or a week. If nobody has answered by then, the email you sent is pinned above your inbox, unread, with one notification. Click it to read it again, or its x to dismiss the reminder; nothing in your mailbox is moved. Replies are looked for in the mail MailVault already holds in any folder but Sent and Drafts, and on the server in your inbox, archive and Trash; mail from your own addresses and aliases does not count, and neither do automatic out-of-office replies. Not offered for Outlook.com accounts signed in with Microsoft.
MailVault has a Discord server. Join it, or follow MailVault on X, from the icons at the bottom of the sidebar or from Report a bug, for questions and chat with other users.
Changed
The sidebar footer is tidier. The six icons (privacy mode, report a bug, refer a friend, Discord, X, light or dark) are one connected block with no gaps. Below it, the email count sits on a single line with a thin progress bar while mail downloads, and a nightly's long build tag moves to its own small line under the version instead of wrapping.
Fixed
IONOS accounts no longer get a false DKIM warning after Change server. The check looks for your domain's DKIM key under a list of common selector names and did not know IONOS's s1-ionos and s2-ionos, so it warned that outgoing mail might be marked as spam even when DKIM was set up correctly. Both are checked now.
No banner for mail you sent. Replying in a thread that lives in your inbox no longer notifies you of your own message. Mail from your login address, default From or any alias is skipped; mail from others still notifies.
A long message in the compose window no longer shows two scrollbars. The whole window now scrolls as one, address rows, attachments and body together, with the formatting toolbar pinned at the top and Send always in reach; the attachment list no longer scrolls on its own either.
Link and tracker warnings speak your language. The sentence under "Dangerous Link Detected" ("Link text shows ... but goes to ..."), the one on a link that redirects through another site or uses a script scheme, the hover text on a flagged link and the reason a tracking pixel was blocked stayed in English in every language, and "(no text)" in the link list too. They now follow the app language, and change when you switch it.
The compose window's To, Cc and Bcc follow the app's language. They stayed English beside a translated From and Subject ("Von:" / "Betreff:" over "To:" / "Cc:" / "Bcc:"). The three captions and the contacts button next to each ("Pick To from contacts") now read in German, Spanish, French, Italian, Japanese, Korean, Portuguese and Chinese.
AI writing answers in the language of your mail. Shorten, Draft a reply, Change tone, Summarize and Action items could come back in English for a German, French or Italian message, because the request to the model was in English only. Each one now asks for the language of the email.
An Auto Tag appears on new mail while you look at it. A message that arrived with its folder open got its tag a second later, but the row showed no chip until you left the folder and came back. The chip now appears on its own, a hide-from-Inbox rule takes the row out of the Inbox the same way, and running or undoing a backfill updates the rows on screen too.
Auto Tags use Apple Intelligence. A rule without "Allow a remote AI provider" only ever asked the downloaded model, so on a Mac with Apple Intelligence and no downloaded model it never tagged anything. It now runs on Apple Intelligence when it is available, else the downloaded model, and Preview says so plainly when neither is there.
Labels, hints and tooltips drop the long dash, in every language. Text that joined two parts with an em dash now uses a colon, comma or hyphen, among them the Time Capsule header ("Snapshot: 8 Oct 2026"), the Scheduled list rows, account tooltips in the sidebar and the restore progress lines. A missing value shows "-", and a folded signature reads "โธ Show signature".
The shortcut chip in Settings shows "Press keyโฆ" again. It read "Press key\u2026", and a two-key shortcut waiting for its second key read "G + \u2026"; the same broken escape showed "provider\u2019s" and "Settings \u203a Accounts" in two English messages.
Alerts break their lines again. Eight "could not save / read / write" error alerts showed a literal "\n\nDetails:" in every language instead of putting the details on their own line, and the MBOX import summary showed a literal "\n\n" too.
Email Cleanup drops the mail you delete or archive. Selecting a group such as Newsletter and pressing Delete or Archive finished, yet every message stayed listed, because Cleanup kept its results for mail the server no longer had. Mail that is deleted, archived and then removed from the server, or moved to another folder, now leaves the Cleanup list and its counts, whether you did it in MailVault or another mail app, and a moved message is sorted again where it now is the next time Cleanup sorts your mail. Archive in Cleanup now saves each message to your vault, checks the copy, then deletes it from the server, as its confirmation says; a message whose copy cannot be checked stays on the server and in the list. Cleanup's Delete and Archive buttons, its progress line and the All preset in Bulk operations now follow the app's language.
Social export has an Email Light/Dark choice, and the background selection shows in full. Under Appearance, a new Email row sets the message body to Light or Dark, as the sun/moon over the preview does and as the reader does in the app. The ring around the selected background no longer loses its left edge.
About twenty more screens speak your language. English text that stayed English in every locale now follows the app's language: "Sign in with ...", "Advanced (Corporate)", "Change server: ...", the restore tray and its "Restore N" button, "Can't reach the server", the search bar's "Popular filters" and "From (sender)", the Backup and MBOX headings and bullets, the Premium unlock button, "(this device)", the Time Capsule note, the spell-check help for snap builds and "Download v..." in the update dialog. The Remove account explanation also no longer shows a literal "\u2019" in place of its apostrophe.
v2.19.1October 7, 2026
Changed
Sending a big attachment is faster. The message was built a second time at the moment it went out; it now goes out as the copy already built for Sent, which also makes the two the very same bytes.
Fixed
Archive works on Outlook.com accounts signed in with Microsoft. On a personal Microsoft account (outlook.com, hotmail, live) every message you archived failed ("Archived with 4 error(s)"), because the copy was fetched from Microsoft's IMAP server with a sign-in that only works for Microsoft Graph. Archive now downloads each message through Microsoft Graph, and a message you had already opened is replaced by its archived copy instead of kept twice. (#23)
The focus scene stays put when you click Unlock early. The diorama no longer jumps up behind the confirm question.
The list toolbar stays on one row. Turning Timeline on in a saved view added a labelled Reset view button, which pushed List and Explorer onto a second row, so the toolbar grew under your pointer. Reset view is now an icon that sits beside List and Explorer from the start and lights up once the view differs from how it was saved. In a narrow list the Unread, Senders, Timeline, List and Explorer labels give way to icons (their names stay as tooltips and for screen readers), so the row holds from a 350px list up; below that the threads selector takes a row of its own.
v2.19.0October 7, 2026
Added
A focus session can run on a calm animated scene. When you start a session, pick Countryside, Sea or Town, or None for the plain lock; the app remembers your choice. The lock becomes a window onto a small pixel-art world whose day follows your session, from dawn when it starts to night when it ends: chimney smoke drifts, sheep graze, a sailboat laps a lighthouse, and windows light up one by one at dusk. The countdown stays at the top, its colour following the sky so it reads clearly from dawn to night, and the scene fits the window at any size and screen scale. With Reduce motion turned on in your system the scene holds still while its light still follows the session, and on a computer that cannot draw 3D graphics the lock looks as it always has.
Changed
Export message fills the window, and opens in a window of its own with all three formats. The export dialog now follows the size of the app window with 32px around it, so the preview and the options have room instead of sitting in a narrow column. Image, HTML and Social are one tab strip, and Open in window takes whichever tab is open into a single window that switches between them, so a message opened there can change format without going back to the app. Back to app returns to the dialog on the tab you were on, with your choices.
Recent searches narrow as you type, and fold away. Under the search box, the recent searches now show only the ones holding the text you are typing; when none do, only the suggestions are listed. Click the Recent searches heading to fold the list, and again to bring it back; the app remembers which way you left it.
Removed
Product Hunt launch page. The launch day is over, so MailVault no longer checks for it at startup.
Fixed
New mail shows up in views and search again. Reading the text in a picture attachment could stall for good on macOS, and from then on nothing new was indexed: views (one filtered by sender, say), their counts and search all stopped at the mail that came before. Reading a picture's or a PDF's text now gives up after a minute, the stuck attachment is skipped, and new mail keeps being indexed.
The unread number beside an account matches its list. When a delete could not reach the mail server (a dropped connection, say), the message left the list but the server still held it unread, so the account showed "1" while its Unread filter said "No unread messages". The number now counts only messages the list shows: not one whose delete is still on its way to the server, one the server marked deleted but has not removed, or one an auto-tag rule keeps out of the Inbox. Changes the server refused are also sent again every five minutes once the Undo prompt has gone; before, anything you could undo (a delete, a move, marking read or unread, a star, a snooze) stopped the retries until the app restarted.
Outlook.com accounts signed in with Microsoft can send mail again. A personal Microsoft account (outlook.com, hotmail, live) signed in with "Sign in with Microsoft" synced fine but failed every send with "Authentication failed for smtp.office365.com:587", because the send went to Microsoft's SMTP server with a sign-in that only works for Microsoft Graph. Sends, scheduled sends included, now go through Microsoft Graph: Sent shows the message once, and a refusal says what to do (sign in to the account again, or use an address the account may send as) instead of blaming the password. A send Microsoft took but never confirmed is not sent a second time: it asks you to check Sent first. (#22)
A scheduled email goes out even when its sign-in expired while the app was closed. For an account signed in with Google or Microsoft, a scheduled email that came due after the sign-in had expired (overnight, say) was sent with the old one and failed. It now renews the sign-in first, and if the computer has only just woken and the network is not back yet, it waits for it instead of giving up. When the sign-in cannot be renewed, it stops and asks you to sign in again.
Sending through SMTP port 465 works. An account whose outgoing server used port 465 (SSL/TLS), such as IONOS, failed every send with "incomplete response": the app asked the server to start encryption on a port where it is already on from the first byte. Port 465 now always connects encrypted from the start, for accounts already added too; port 587 keeps using STARTTLS. (#21)
An attachment open in the app no longer reloads under you. A PDF opened from an email's attachment bar flashed and reloaded again and again while you read it, because every small change to the row (a download finishing, the list repainting) reloaded the frame. The preview now loads once and stays put until you close it.
Inline pictures from Outlook mail show up instead of an empty box. A message that embeds a picture (a pasted screenshot of a spreadsheet, say) could open with a large bordered rectangle and nothing in it. Outlook writes the picture's address with its @ percent-encoded, so the reader never matched it to the attached image and never loaded it. The address is now decoded before matching, in the reading pane, the cache, exports, and replies and forwards.
A forwarded HTML email arrives looking like the original. Forward used to put the original into the editor, which dropped its tables, colours and styles, so a newsletter or receipt went out as plain stacked paragraphs, and its inline pictures arrived broken beside loose attachments. The original now stays out of the editor, opens in the panel beside it, and goes out exactly as it arrived, with its inline pictures in place. You write your note above it; the forwarded message itself is no longer editable. A reply or forward reopened from Drafts, or a scheduled one opened for editing, keeps its original beside your text the same way, instead of pouring it into the editor where its formatting was lost.
Text on Linux keeps its word spaces. With the default Instrument Sans font, the Linux app (Snap included) drew small text with spaces missing and letters pulled apart, so "Its contents" read "Itscontents" and "message" read "me ssage", at 12 and 14 pixels, the size of most of the app's text. The app now bundles the font's four regular weights instead of its variable version, which Linux's web engine laid out wrongly. The few labels set between semibold and bold now draw in bold.
The online check reaches a mail server through any of its addresses. When a server's name gave more than one address, the check tried them one after another inside its 1.5 seconds, so a first address that refused (an IPv6 address where the server only listens on IPv4, say) could use up the time, most of all on Windows, which retries a refused connection. On a network that also blocks the public DNS servers the check dials, the app then read a working connection as offline. All of a server's addresses are now tried at once.
v2.18.1October 4, 2026
Changed
Social images start with the corners of a macOS window. The Corners slider's default and its macOS mark are now 12, the corner radius of a macOS window, instead of 26. A saved style on the old 26 moves to 12; any other radius you picked stays as you set it.
Open in window and Back to app sit at the top right. In the export dialog, Open in window for a social image is now beside the close button, and the social image window has a title with Back to app at its top right, leaving Close and Save at the bottom.
Pick how wide the email is in a social card or a PNG export. A new Email width slider, from 480 to 1600 pixels, sets the column the message is laid out in, so a wide newsletter no longer has to squeeze into 820 pixels. The social card remembers it; the preview updates once you stop dragging, and Save uses the width the preview shows. HTML exports keep their usual width.
A sun and moon button on the social image preview switches the email between light and dark. It works like the one in the reader and replaces the Email content buttons. It now also applies to the app window shot, so the message in a shot of the app can be light while the app is dark, or the other way round, without changing the reader.
The export dialog previews Image and HTML exports. Like a social image, an Image or HTML export now shows a preview beside its options, for one message or a whole thread, and updates as you change them. Attachments are left out of the preview, and turning on Redact sensitive info, or privacy mode, takes the unredacted preview away at once.
Fixed
The snap no longer says "No internet connection" on a working connection. On Linux the Snap package could not ask the desktop whether the network was up, so the window believed it was offline from launch: the banner stayed up through Check again, a folder could open showing only what was saved on this computer, and read marks, moves and deletes made in the meantime waited to be sent. The snap now asks the desktop with the network status permission it needed, and on any build a check that reaches the internet clears the banner even when the desktop still reports no network. (#16)
The tray icon on Linux and Windows is as large as its neighbours. It used the app icon with the transparent margin a macOS icon keeps around its artwork, so it drew about a fifth smaller than the other icons in the GNOME top bar. The tray now uses the artwork alone. (#16)
v2.18.0October 3, 2026
Fixed
Search says how long the vault and the server each took, in a form no locale misreads. The line under the search box showed one total, and switched to milliseconds as a grouped number, so in a language that groups with a dot "7.355 ms" read as seven milliseconds instead of seven seconds. It now gives the vault and the server a group each, with what each found, how many messages it read and how long it took, such as "Vault 12/8,922 ยท 294 ms" and "Server 6/7,179 ยท 8.52 s": milliseconds under a second, seconds from one up. The vault's numbers show as soon as it finishes, while the server is still searching, and Save view sits at the end of the results line.
Tags, custom fields and views no longer fail to save with "database is locked". The app and its background service share one settings database, and a change that first looked something up (creating a tag, assigning one, saving a field or view) was refused at once whenever the other side was writing at that moment. It now waits its turn, for up to five seconds.
Auto Tags no longer says "Could not decide" when Apple Intelligence answers briefly. A reply such as "yes 0.9", "YES" or "NO" followed by a confidence line was refused because it left out the MATCH: label. Those short answers are now read, a bare yes with no confidence counts as a full-confidence match, and a reply that cannot be read as a clear yes or no is still refused.
Signatures made with a signature generator keep their layout. In Settings, a signature pasted into Code view lost its tables and inline styles (a coloured border, spacing, a button-style link) and arrived as plain paragraphs. Such a signature is now kept whole: it shows in compose as it will look, is selected and deleted as one piece, and goes out exactly as written. Scripts, forms, event handlers, unsafe links and styles that load something are still removed. (#19)
Forwarding a message with attachments sends again. Forwarding a message you had opened, from your vault or the server, failed with "Could not prepare the outgoing email: Missing or invalid email", and its draft was never saved, because the forwarded attachments were copied without their files. The files are now read from the original message when you forward it, and if one cannot be read the error names it.
The dock badge counts the same unread mail as the sidebar. The dock badge also counted the last unread number of accounts no longer in the sidebar, so it could show more than the account rows added up to. It now adds up exactly the accounts the sidebar lists.
Bulk Email Operations work on messages from more than one folder. In All Inboxes, in a folder shown with its subfolders, or with a Sent copy, a search result or another account's message ticked by hand, Archive, Delete from Server, Archive & Delete and Archive, Back up & Delete failed as a whole, or in All Inboxes asked for a folder that does not exist. Picking a date range in a folder shown with its subfolders also read the top folder alone, leaving out subfolder messages that share a number with one in it. Each message is now handled in its own account and folder. A message whose folder cannot be told, or that sits in a folder kept only on this computer, is skipped and counted in the result instead of stopping the rest of the run.
A message you undid a delete on is listed when you come back to its folder. After Undo, leaving the folder and opening it again could leave the restored message off the list even though it was back on the server, until a full refresh. The list now rebuilds its threads whenever a message in it is replaced by another, which is what Undo does to give the message its new number, and Undo drops the copy of the folder the app remembered from before the delete.
Opening a message no longer waits for the mail server's answer to the read mark, and an Outlook account offline no longer shows an error for it. The message body appeared only after the mark had been journalled and sent; it now appears as soon as the list has changed, and the mark finishes in the background. On an Outlook account that could not be reached, opening a message put "Could not update the flag on the server" in the error banner for a read mark you never asked for; it is now only logged.
A message you open while a folder cannot be reached no longer turns bold again. When the password lookup, the offline check or the load itself failed a moment after you opened a message, the list went back to the state from before you opened it, and the unread count moved by one. A folder with subfolders did the same while it was still filling in.
A message you just opened no longer turns bold again after a folder loads. Opening a message while its folder (or All inboxes) was still loading marked it read, and when the load finished it put the old unread state back, in the list and in the copy saved on disk. Flags you change while a load runs are now kept.
Deleting or losing an Inbox message no longer hides an unrelated one. In the Inbox list, a message from your Sent folder that shared the deleted message's internal number disappeared with it, and opening a message in All inboxes could put the attachment mark on another account's message. Each message is now matched only by the account and folder it is in.
Undo after marking search results read now restores only what changed, and undoing a move of search results works on every server. Marking ten search results read when three were already read, then undoing, marked all ten unread; undoing a move of search results could fail on a mail server that does not report where the moved messages went. Search results now count like the messages in the list.
A message you open from search now stays read. While a search was still running, opening a result marked it read, and the next batch of results could turn it bold again. The read mark now holds for the rest of the search.
Quick actions changed for All views reach every view. A view customized in Settings > Appearance > Quick actions with Scope on Current view kept a full copy of every setting, so later changes to All views, and new actions such as Snooze and Unsubscribe, never reached it: one inbox could keep showing a menu in the reader while every other view showed buttons. A view now keeps only what you set differently for it and follows All views for everything else; views customized before are converted on update, keeping their own choices. Settings says when the view you are on differs from All views, with a Use All views button to drop the difference, and a Settings window of its own now follows the folder you move to in the main window.
Quick actions offer the same choices in the message list, on the selection bar and in the reader. A saved "Move to" a folder that only groups other folders and cannot hold messages is now unavailable everywhere, not just on the selection bar. Ticking an archived message from another account or folder, or in All Inboxes, now offers Unarchive on the selection bar instead of Archive. Unsubscribe on the selection bar, which did nothing when clicked, is now greyed out, since it works one message at a time. Star and Unstar on the selection bar wait until every ticked message is loaded, as Mark read already did, and Delete everywhere there is offered only when a copy exists beyond the server (in your vault or on your backup drive), as in the message list. In a folder you imported to keep only on this computer, Archive is no longer offered in the list or on the selection bar, matching the reader: that mail is already in your vault. The Bulk Email Operations window now counts those hand-ticked archived messages as in your vault too, and its Unarchive removes their vault copies instead of skipping them. In Server view, a message already in your vault now offers Unarchive instead of Archive in the message list, on the selection bar and in the reader. Its status icon and the reader's storage line say it is in your vault, and its row plays the brief highlight when you archive it. A delete confirmation in the reader no longer says a message from another folder is kept in your vault when it is not.
The snap no longer stalls on desktops with automatic login. A desktop that signs in without a password keeps its keyring under the name "Default keyring" instead of "login", and the Secret portal never answered for it, so MailVault waited for ever and could not read or save an account. It now waits four seconds at most, then uses the system keyring as it does on a desktop without the portal, and says to run sudo snap connect mailvault:password-manager-service when that is not allowed.
A message marked read or unread on another device now changes everywhere it is shown. The list turned bold or plain, but the open message, its conversation, and a search result kept the old state, and the open message still offered the wrong Mark read or Mark unread button. All of them now follow.
A message you open is now marked read the same way as one you mark by hand. Opening one marked it on the mail server first and the list only afterwards, so the row stayed bold until the server answered; if the server refused or you were offline, it stayed bold and the change was never retried. The row now turns read at once, and a change the server could not take is kept and sent when it can.
A message you marked read in All inboxes stays read when you switch folders and come back. Switching from one All inboxes folder to another and back painted the list from a copy kept from before, so the message turned bold again, and a refresh could do the same from the copy kept for switching accounts. Leaving a folder and returning to it after marking one of its messages from All inboxes or a search result could show it bold as well. Every such copy now takes the change.
The unread count on an account no longer jumps to a wrong number, and the dock badge follows it. Marking a Sent or Archive message read in All inboxes, or a message in a folder branch, replaced that account's Inbox count with the number of unread messages in the folder on screen, and in a large Inbox the list's partial window did the same. Marking read, moving or removing a message now changes the count by one, and the dock badge, which used to wait for the next refresh, changes with it.
Deleting a message in a folder branch no longer hides another folder's message. Viewing a folder together with its subfolders, deleting message number 34 of the parent folder also hid the subfolder's message 34 until the next reload, and a message deleted inside a subfolder could come back in the list for a moment.
One account's saved message no longer marks another account's as saved. In All inboxes or a folder with subfolders, archiving a message in one account or folder put the vault mark on the message with the same internal number in every other account or folder, hid a "deleted on the server" message that should stay hidden, and could show another account's vault copy in the list. The vault marks are now kept per account and folder.
Bulk Operations no longer includes messages the list does not show. Choosing All in Bulk Operations also took in messages an Auto Tags "hide from Inbox" rule keeps out of the Inbox and messages held by a local snooze, so a bulk archive or delete could act on mail you could not see. It now uses the same rules as the list. A folder with subfolders also no longer hides a subfolder's message because the parent folder's message with the same number carries a hidden tag.
A vault copy can no longer take another account's details or status. When two accounts (or two folders) held a message with the same internal number, archiving one in bulk could record the other's subject and sender in the vault, the server-wide check behind "your only copy" could look for the wrong message and mark yours as deleted by someone else, the open message could show another account's copy status, and deleting an Inbox message could be treated as removing a staged Sent copy instead. Each now follows the message's own account and folder.
Search results in All Inboxes name the folder searched. The line under the search box said "Found 221 results in UNIFIED"; it now says "in Inbox across all accounts" (or Sent, Drafts and so on).
Search no longer says the index is still being built after it has finished. A search in All Inboxes, or in any folder an account had never saved a message to (an empty Drafts, a Sent folder one account does not have), kept showing "Indexed results are still being built" for ever, because the index never lists a folder that holds no mail. Such a folder now counts as searched and empty, and the notice shows only while folders with mail are still waiting for the index.
JetBrains Mono draws its extended Cyrillic letters. Letters such as those of Abkhaz or Chuvash fell back to another typeface in JetBrains Mono, because their font file was the one small enough to be packed into the app's stylesheet, where the app's security policy refused to load it. Every font now ships as its own file.
Added
The Social image preview zooms, and opens in a window of its own. Under the preview, Fit shows the whole image, 100% shows its actual pixels, and minus and plus step between, scrolling the preview when it is larger than the box. Open in window moves the export to its own resizable window, where the preview takes all the room the window gives it; Back to app returns it to the Export dialog with the same choices. Redaction and privacy mode apply in the window exactly as in the dialog.
Privacy Policy in Settings. Settings > Help links to MailVault's privacy policy, which now spells out how Gmail data is handled: it stays on your computer, is never sold or used for ads or AI training, and is deleted when you remove the account.
The menu bar icon lists your accounts with their unread counts, and opens Compose. Click the MailVault icon in the menu bar (the tray icon on Windows and Linux) for Compose at the top and every account in sidebar order with its unread count; choosing an account brings MailVault forward on its Inbox. On macOS a click on the icon now opens this menu; Show MailVault is in it.
Privacy mode (Premium). One click in the sidebar masks names, email addresses, phone numbers and postal addresses across the message list, reader, threads, chat view, sidebar, attachment names and notifications, so you can record your screen or read mail in public. Hold Option (Alt) to peek; shortcut Cmd/Ctrl+Shift+P. Avatars and text inside images are not masked. The raw source view and Open in window are blocked while it is on.
Export can redact sensitive info. The new "Redact sensitive info" option masks names, email addresses, phone numbers and addresses in exported images and HTML (blur or black bar); links and remote images are stripped from redacted exports. Attachments are renamed but their contents are not redacted, so they start switched off. With privacy mode on, export starts with redaction on.
Share a message as a styled image (Premium). Export has a new Social format for one message: the email as a card, or the whole app window with it open, on a gradient, a solid color, your own two colors, your own picture or a transparent background, sized for posting (Auto, 1:1, 4:5, 16:9 or 9:16) with padding, rounded corners, a shadow and a window frame. A live preview follows every change, and Save PNG writes the image at twice the size. Sensitive info is redacted by default every time, and always while privacy mode is on. The whole email always fits the image, shrunk rather than cut off. Like the app, there are two themes: Appearance (Light or Dark, the app's own theme until you pick one) styles the window frame, the card's header and the app window, and a card's Email content can be Light or Dark on its own, so a dark header over a light email works too. The style you pick is remembered, your own picture is not. Every image carries a small lockup in its bottom-right corner: the MailVault icon, "made with a heart by" and the Graphic Meat logo, in lettering that reads on any background. To name a spammer, Show sender keeps a spam message's sender readable (on by default in the spam folder) while everyone else stays redacted; Sender details adds the sender check from the reader (authentication results, Reply-To mismatch) to the image, and a card's Links lists where the message's links really go, worst first, with only the site shown when redacted. Corners start at the macOS window radius, and a tick under the slider snaps back to it.
Hide the menu bar on Linux. Settings > Appearance > Layout > Menu bar hides the File and Logs strip under the title bar, in every MailVault window. From the next launch the bar is not built at all, so it never flashes in. Check for Updates is now also in the tray menu on Linux, so it stays at hand with the bar hidden; Settings, bug reports and logs already are.
The search bar builds a search out of tags, and suggests what to search for. Each word, operator and recent search you add becomes a tag, like the recent-search tags under the box. Press Enter to add what you typed as a tag; adding, removing or changing a tag runs the search at once, with no second Enter. Click a tag's x to remove it, or its text to change it in place. Backspace or the left arrow in an empty box moves to the last tag. Type / at the start of a word to pick an operator such as from:, has:attachment or before:, then type its value. While you type, senders and words from your saved mail are suggested under your recent searches; they come from the search index, and while it is busy or off the box simply shows none.
Search says how long it took and how much mail it read. The line under the search box now shows the time the last search took, in seconds (click it for milliseconds), and how many saved emails it read, as in "Found 221 results in Inbox across all accounts from 48,000 emails". Next to it, each source is counted against the mail it searched: "Results: 33/10,000 local, 3/2,150 server". The items on that line now sit on one baseline.
Edit a signature as HTML. The signature editor, for an account and for an alias with its own signature, has a Rendered / Code switch. Code shows the signature's HTML, one block per line, to read or edit by hand; switching back shows the result. Whatever you type is read through the same filter as the rendered editor, so scripts, styles and markup the editor does not support are removed, pictures and links are kept, and HTML that is broken is repaired rather than lost.
More fonts from Google Fonts, for the app and for signatures. Settings > Appearance > Text has More fonts (Google Fonts): about 130 families to search and browse by category, with no connection needed to look. The font you choose is downloaded once, font files only and no personal data, kept on this computer, and shown in Network Activity as Fonts; downloaded fonts are listed beside the built-in ones and can be removed again. Offline, the choice says so with a Retry, also under More fonts after the list is closed, and text keeps its current font until the download finishes. The signature editor has a font control with common fonts, the app's fonts, downloaded ones and More fonts, for the selected text or the whole signature. Most mail programs cannot load such a font, so the signature names a similar common font after it, which is what recipients without it see; no font file is attached to or linked from a message.
Received mail shows the Google Font it was written in. A message set in one of the Google Fonts MailVault offers now draws in that font instead of a stand-in. MailVault downloads the font once, like one you pick in Settings, so it appears in Network Activity and in your list of downloaded fonts; with tracker blocking on, a message never downloads one, but still uses a font you already have. A message can no longer fetch fonts from Google by itself.
Changed
Links from the app to mailvaultapp.com say where they came from. Upgrade, Premium, FAQ, help and website links opened from MailVault now carry utm_source=app and the place they were opened from, so the site can tell visits from the app apart. Nothing about you or your mail is added.
A forward keeps the fonts of the message it forwards. The forwarded original sits in the editor, which used to drop the font set on its text; it now keeps the font name, and nothing else of that styling.
The update window shows it is loading the release notes. While MailVault reads what changed from GitHub, the notes box now shows a few shimmering lines (still, with Reduce motion on) instead of staying empty or jumping in late; notes the update feed already carries stay on screen above it.
Gmail messages only go to on-device AI. Mail from a Google account is only ever handed to Apple Intelligence, the downloaded model or an Ollama server on this computer; if your AI provider is a cloud endpoint, Gmail mail uses an on-device provider instead, or the AI action is unavailable when none is set up.
Choose which Google app signs you in to Gmail. Gmail sign-in still goes through Thunderbird's Google app by default. A new option in Settings > Accounts, and a choice when you add a Gmail account, let you sign in through MailVault's own Google app instead. Google is still reviewing it, and it becomes the default once approved. Switching asks you to sign in to Google again, and a plain Reconnect keeps the app the account already uses. Gmail accounts you already added keep the app they signed in with.
v2.17.1September 30, 2026
Added
Type "/" in a message for a command menu. Writing a message or a signature, "/" at the start of a line or after a space opens a menu under the cursor: Emoji, Bulleted list, Numbered list, Quote, Code block and Divider. Keep typing to narrow it, use the arrow keys and Enter (or a click) to pick, Escape to close. Choose Emoji, or type "/emoji", to search emoji by name; "/rocket" finds the emoji straight away. More commands will follow.
Code looks like code in a message, written and read. Text between backticks and blocks fenced with three backticks were already shown as code while you wrote; now the message carries that look with it (monospace type on a soft grey background), so mail clients that ignore styles still show it as code, and the editor toolbar has a button for inline code beside the code block one. When you read a message, code the sender styled is left as they made it, unstyled code in an HTML message gets the same monospace look, and in a plain-text message backticks and three-backtick blocks are shown as code too.
Product Hunt launch page. From 12:01 am Pacific on 4 October 2026 (10:01 am in Vilnius) for 24 hours, whatever your timezone, MailVault opens on a full-screen orange page asking you to support the launch on Product Hunt. While MailVault is in the background the words PRODUCT HUNT sweep across the screen; when you switch to it the sweep finishes and the cat and the Support button animate in. The page has no close button: the Support button opens the launch page in your browser and then takes the page away for good. Until you press it, MailVault stays behind the page. A small note under the button says when the page ends in your own timezone and how much time is left. If you are new, the page waits until 10 minutes after you finish setting up MailVault.
Changed
The window fits the screen on Windows. On a 1920 ร 1080 screen at the 125% or 150% scaling Windows sets for most such screens, the window MailVault opened in ran under the taskbar. It now opens at 1100 ร 600, and on a screen with even less room it shrinks to fit above the taskbar and opens centred.
v2.17.0September 30, 2026
Added
Resize a signature picture, and get a sharp file. The signature editors in Settings > Accounts (the account's and an alias's own) now have an Insert image button, take a picture dragged in from Finder or pasted, and show corner handles on a picture to resize it. After you resize, MailVault offers to store the picture at three times the size it is shown at (a logo shown at 40 ร 40 becomes a 120 ร 120 file), which looks sharp on every screen and is usually much smaller. The offer shows the file size now and after, and the picture as it will look; Keep original leaves it alone, and nothing is offered when the file is already that small.
Compact or comfortable message rows. Settings > Appearance > Layout > Message list density switches the list between the current comfortable rows and tighter compact ones, like the sidebar density beside it.
Move a compose window back into the main window. A message you are writing in its own window has a button in its header that brings the draft back into the main window, content intact.
Signature logo size guidance. Settings > Accounts shows how large the logo in your signature is: under 100 KB is ideal, 100 to 200 KB gets a warning, and more than 200 KB is flagged as too large, with the recommended size next to the editor.
Choose how an MBOX file is imported. After you pick a file with Import MBOX in Settings > Backup & Restore, a dialog asks which account it is for and offers three ways to bring the mail in: Import and restore to the server, Import into my existing folders and Import as a separate folder. Import into my existing folders is the default: it saves the mail in your vault, in the folders the account already has, and uploads nothing. Messages that are already in the target are skipped.
Google Takeout files are filed by their Gmail labels. When a file carries Gmail labels, Use Gmail labels (on by default) files each message by them instead of putting everything in one folder. A message goes to Inbox, Sent, Drafts, Spam or Trash when it has that label, in that order; otherwise to a folder named like one of its labels, taking them in the order the message lists them; otherwise to a fallback folder you pick, which starts as All Mail on Gmail and Archive on other accounts (Inbox when there is none). Import into my existing folders never creates a folder, so a label with no folder there falls back, while Import and restore to the server creates the folder on the server first. Starred keeps its star, a message is unread only when it carries the Unread label, and the Important and Category labels are ignored. A file without labels goes to the one folder you choose, Inbox to start with. Import as a separate folder does not sort by labels.
Import an MBOX file as a separate folder, kept on this computer. Import as a separate folder puts the whole file in a new folder named MBOX import and the date, such as MBOX import 2026-09-29 (a second import on the same day adds a number), under a new On this computer heading in the sidebar. The folder lives only in your vault: it is never uploaded to a mail server or merged into one. You can read, search, star and mark its messages, export them and delete them (a deleted message goes to Deleted emails), and delete the whole folder from its right-click menu, which sends its messages to Deleted emails first. Moving, snoozing and archiving mail are not offered there. Backups keep a copy of it in a folder of its own on your backup drive, and ZIP exports include it.
Restore an MBOX file to your mail server. Import and restore to the server uploads each message to the account, into the folder its label names (created on the server when it is missing) and with its original date, so every device sees it; a message the server already holds is skipped. It is for IMAP accounts: on an Outlook account that uses Microsoft Graph the option is disabled and says why. The upload runs in the background, one per account at a time, and its progress is a small card in the corner with Pause, Resume and Cancel, so MailVault stays usable meanwhile. When the server limits uploads, MailVault waits and tries again by itself. A large file warns that the upload can take many hours, and a time estimate appears only once MailVault has measured its speed. Cancelling, quitting or a crash does not lose the place: the card offers Resume where it stopped (MailVault may ask you to pick the file again), and starting the same file again offers Resume or Start over. If the server refuses the sign-in, the upload waits and the card offers Account settings. On Gmail, a message's other labels are added after it is uploaded; that depends on Gmail accepting the change and is best effort, so a message whose labels are refused stays in its folder without them.
See which messages are not in your vault yet, and save them. Each account's card in Settings > Backup & Restore > Backup Schedule now shows Not yet in your vault: how many copies of messages MailVault has shown or cached whose full copy your vault does not hold (a message kept in two folders counts once in each). Save them now downloads them into the vault. A count that cannot be complete says at least, and if the vault cannot be reached the count is shown with the reason. An account whose download mode keeps mail on the server by design says so instead of counting, and Outlook accounts show the count but cannot use Save them now.
Aliases for every account. Settings > Accounts has a new Aliases section that lists every address an account sends from: its login address, which stays as it is, then each alias. For a Google account signed in with Google, MailVault fetches the aliases Gmail lets it send as; for any other account it finds the addresses you have sent from in your own mail, suggests the ones your mail arrives at, and you add the rest by hand. Give each alias the name recipients should see: a name typed on an alias is what goes out on mail sent from it. Pick which address new messages start from, and use Verify to send one test message from an alias and see whether your provider accepts it. The Send Mail As field that sat under Profile now lives here, and the From row of a new message has an Add address link that opens this section for its account.
Adding an account says what it reached. When the connection test passes, the add-account window says which server MailVault connected to, how many messages are in your Inbox and the address your mail will be sent as, for example "Connected to imap.example.com. 1,204 messages in your Inbox. Mail will be sent as [email protected]." A wrong server or a wrong sending address shows up right away, not after your first sync or your first reply. Reading the count adds one quick, read-only request to the test, and the window still closes on its own as before. The count is left out when the server does not give it within a few seconds, and Outlook accounts connected through Microsoft Graph do not show this line.
A signature for each alias. In Settings > Accounts > Aliases, every alias has a Signature choice: the account's signature, which it follows by default, or its own. Choosing Its own starts you from a copy of the account's signature to edit, and an own signature left empty sends from that address with no signature. In a new message, a reply or a forward, the signature follows the address in the From row: pick an alias and its signature replaces the previous one, whatever you have typed stays, and picking the login again brings the account's back. An alias's own signature is used even when the account's signature is switched off, and one that follows the account follows its switch too.
Archive, back up & delete from server *(Premium)*. Settings > Backup & Restore > Archive & delete can now clear a whole account, or just the folders and years you pick, off your mail server while keeping every email. Choose an account, tick the folders, then choose the dates: All dates, This year, Last year, Older than 2 years, or Choose years, which lists each year with its number of emails. MailVault saves each email into your vault and onto your backup drive, checks both copies, and only then removes it from the server. Choose when it deletes, after everything is saved or as each email is saved, and how: Move to Trash, or Move to Trash and empty it, which removes from Trash only the emails the job moved and leaves the rest of Trash alone. Before you start, a summary shows how many emails and how much data are involved, how many are already saved, and how many days it should take at your daily limit, and you confirm it with a tick. An email whose copy in the vault or on the drive cannot be confirmed stays on the server, and if the backup drive is disconnected the job pauses and carries on when it is back. It needs a backup folder, and is greyed out with "Choose a backup folder first" until you choose one.
Archive & delete from server *(Premium)*. The same job for people who keep one copy: it saves each email into your vault only, checks it, and removes it from the server. The card says plainly that your vault will be the only copy, and points to Archive, back up & delete for a second one. Both jobs show their progress in a panel in the corner of the main window that you can minimize to a small pill and reopen from it. They keep running when you close the window, carry on by themselves after a restart, wait for the next UTC day when your daily download limit is spent, and wait and try again when Gmail or another server asks them to slow down. On Gmail, an email that carries several labels is removed from all of them. Outlook and Google accounts keep signing in for as long as MailVault is open; while it is closed, their job waits.
Archive, Back up & Delete *(Premium)*. The bulk dialog (Select messages) has a new action that copies the selected messages into your vault and onto your backup drive, checks both copies, and only then removes them from the server. A message either check does not confirm stays on the server; when the backup drive cannot be reached or a copy does not match, nothing is deleted for those messages and the result says how many stayed and why. The action needs a backup folder: until one is chosen it is greyed out with "Choose a backup folder first".
Shift-click to select a range of messages. With one message ticked, or one open, hold Shift and tick another above or below it: every message in between is selected too, conversations included.
See the connections MailVault makes. Settings > Privacy & security > Network Activity lists, newest first, the connections MailVault and its background helper make: mail sync and sending, sign-ins, DNS lookups, backups, AI model downloads, release notes and unsubscribe requests. Each row shows the time, direction, protocol, host (its address on hover), port, purpose, account, data sent and received, how long it took and how it ended. The account column names, by its address, the account each connection was for, including Outlook requests, sign-in renewals, sender logos, unsubscribe requests and the remote content an export saves; a connection made for no account, such as the update check, says "Not tied to an account". Filter by protocol, purpose or account, pick a time range from the last hour to the last month, pause the list to read it, or copy what it shows as text. A world map shades each country by how many connections went there; point at a country for its connections, data and busiest hosts, or click it to list only its rows, and connections inside your own network are counted beside the map. Countries come from the DB-IP country database built into MailVault, so no address is ever looked up online. Above the list, the hosts contacted and the data sent and received in the chosen range, and how many remote images in the emails you opened were blocked by tracker blocking or allowed to load. The page also says what it does not list: web content inside emails, requests the app window makes itself, app update downloads (and on macOS the update check too), and mail connections that are still open. The history stays on this computer only, for 24 hours, 7 days (the default), 2 weeks or a month as you choose, and a portable copy never takes it along.
Notes to Self: a board for mail you send yourself. Notes to Self, above your views in the sidebar, gathers every message you sent from one of your accounts to your own addresses, across all accounts, as cards on one page. Put a #tag in the subject and the note gets a column of its own, so #recipes Pasta lands under Recipes; anything else is sorted into Links, Files, Photos or Notes by what it holds. A card shows the subject, the first lines, the sites it links to, its attachments with a preview of the first photo, the date and which account it came from. Click a card to read it, copy or open its link, star it to keep it at the top of its column, mark it done to take it off the board, or delete it from the server, whichever account it came from; a deleted note keeps its saved copy in your vault and gets the Done tag so it stays off the board. The note you are reading has the same star, done and delete buttons above it, and a button beside its close button opens it in a new window. A button that cannot act on a note, like delete for a note in a folder MailVault has never loaded from the server, is greyed out and says why. A done note only gets the Done tag in MailVault, nothing changes on the server, and removing the tag brings it back. Type in the filter to narrow the board at once; / jumps to the filter and the arrow keys move between cards. Buttons at the top of the board show or hide each account's notes, and MailVault remembers which are on. Select all and Deselect all switch every account at once, and right-clicking an account shows every account but that one, or only that one. Opening Notes to Self takes the highlight off the view or folder you came from, and clicking any view in the sidebar leaves it again. Works from any phone: just email yourself.
Pick where mail and its backup go before adding an account. The first run of onboarding now starts with a storage step: the mail folder MailVault reads and syncs, a backup folder for a separate safe copy that keeps mail even after it is deleted from the server, and the download mode that decides how much mail stays on this computer. Each row is the same control as in Settings, so a folder chosen here is checked for real write access right away, and pressing Continue without changing anything keeps the defaults. The Mac App Store version shows the backup folder and download mode only. Replaying the tour with accounts already set up skips this step. Choosing a backup folder in Settings > Backup now runs the same check at once and says why a folder was refused, instead of waiting for the next visit.
Choose how much mail stays on this computer. Settings > Storage > Download mode offers four modes, and Settings > Accounts > Advanced can give one account its own. On Demand downloads nothing ahead: a message is fetched when you open it and not kept, and full-text search covers only mail kept on this computer. Keep Recent, the default, keeps the last 1, 3, 6 or 12 months; after updating, it removes cached copies older than that from this computer, while the server keeps its copy. Index Only downloads the same period, indexes it for search and then removes it, and opening a message shows its preview at once while the full message downloads. Hoarder *(Premium)* downloads every folder and all history in the background and keeps it. If you had "All emails" chosen, you are on Hoarder now, and without Premium it keeps mail exactly as before. Backups and archived mail are never removed by any mode, and a lapsed Premium never deletes anything.
Download a month or a year of a view's attachments from its timeline. When a saved view shows the timeline and its messages span more than one month, each month header has a button that saves every attachment from that month, and the first month of each year also has one for the whole year. You pick the folder, the header shows the progress, and the other timeline buttons wait until it is done. A month or year that is only partly inside the view saves only the part the view covers.
Group the quick actions wheel into categories. In Settings > Appearance > Quick actions, Wheel layout > Categories turns a radial wheel into a short inner ring: Send, Mark, Organize, Clean up and More, each as a wide, easy target. Point at a category, click it or move to it with the keyboard, and its actions fan out beside it; your actions sort into their categories on their own and keep the order you gave them. A category with one action shows that action directly, and one with nothing that applies to the message is left out. One ring, the default, keeps the wheel as it was.
Start from the quick actions of Gmail, Outlook or Thunderbird. Settings > Appearance > Quick actions and the quick actions step of onboarding now begin with action sets: MailVault's own, and the ones Gmail, Outlook and Thunderbird offer on a message row, over selected messages and on an open message, each drawn as the row it gives. One click sets the message rows, the selection bar and the email reader together, for all views, or for this view alone with Scope on Current view. The set in use is outlined; once you change an action or a layout it reads Custom, and you can pick a set again at any time.
Help for the search operators. A help button in the search box lists every operator MailVault understands, with an example of each; click an example to add it to your search. The first time you search, a small tip points to it. A search written with operators is kept in your recent searches exactly as you typed it.
Web and email addresses in a message are clickable. An address written as plain text in a message, or a link the sender left without a target, now opens like any other link.
Choose the app's font and text size. Settings > Appearance > Text, and the Appearance step of onboarding, let you pick the font MailVault's own screens use: the system font, Instrument Sans, Inter, Atkinson Hyperlegible Next, IBM Plex Sans or Source Sans 3, or a coding font (JetBrains Mono, Fira Code, IBM Plex Mono). Every font ships inside the app, so it looks the same on Mac, Windows and Linux and needs no internet. Text size scales the whole window from 90% to 150%. Emails keep their own fonts.
The original beside a reply reads like the reading pane, and remembers how wide you made it. A reply shows the message it answers the way the reader does: the whole conversation, your own sent replies included, with the message you are answering open and the rest folded. Nothing on it acts: there is no reply, unsubscribe or other action there, and an email address in it does not start another message. Web links still open in your browser. It opens in your email theme and has its own light and dark switch; the pop-out window and a reply in its own window get the switch too. Drag the divider, or pick the half-and-half or narrow-original layout from the icons above it, and every reply after that opens the same way. Neither side can be squeezed below 10% of the window. Reset compose layout in Settings > Mail preferences > Behavior puts it back. A button left of Minimize in the compose header shows or hides the original, and takes no space when it is off.
Read OpenPGP-encrypted mail. Import your OpenPGP secret key in Settings > Privacy & security > Encryption, by pasting it or choosing its file, and MailVault decrypts PGP/MIME and inline-encrypted messages on your device, with no GnuPG needed. The key and its passphrase are kept in your system keychain so decryption happens on its own. A decrypted message says so above its body, and one that no imported key can open says to import your key instead of showing the scrambled text. The first time a message in your vault is decrypted, MailVault keeps a decrypted copy beside the encrypted original, so it stays readable and searchable even without the key; the original is never changed, and deleting the message from your vault, clearing cached mail or purging orphaned mail removes the copy too. MailVault only decrypts: sending encrypted or signed mail and checking signatures are not supported.
See the start of each message in the list. Settings > Workspace > Preview lines shows one, two or three lines of a message's text under its row, in every row style and in threads. The text comes from the offline search index, so it covers the mail already in your vault as well as new mail, and a message the index has not read yet simply shows no preview. Off by default, which keeps the list exactly as it was.
Pick senders and tags for a view as you type. In the view editor, the sender field suggests the people and domains your indexed mail actually comes from, with how many messages each has sent, and the tags field offers your tags by name. Use the arrow keys and Enter, or click, to add one; anything else you type still works as before, and Backspace in an empty field takes off the last one.
Words and phrases for a view, suggested as you type. In the view editor, typing two letters or more into "Add a word or phrase" lists the words and phrases that start with them in the subjects and attachment names of your indexed mail, from every folder, sent mail included, with how many messages carry each. The 20 most common come first, and scrolling to the end of the list, or arrowing past its last entry, brings the next 20.
Unsaved view changes are no longer lost by leaving. If you edited a view and then pick another view, another Settings page or close Settings, MailVault lists what you changed and asks whether to save it, discard it or keep editing.
Settings search takes you to the setting itself. Clicking a result opens its page, scrolls the setting into view, briefly outlines it and puts the keyboard on its control. Backup results now open the right tab too, whether that is Backup & Restore, Backup Settings or Backup Schedule.
The update window lists what changed. When a new version is offered, MailVault shows the release notes of every version between yours and the new one in a scrollable list, read from the project's GitHub releases. If they cannot be fetched, the notes that came with the update are shown as before.
Take MailVault with you on a drive *(Premium)*. Settings > Portable copies MailVault to a USB stick or external drive, with a MailVault Data folder beside it holding your accounts, settings and, if you like, all your mail. Opened from the drive on any computer, MailVault uses that folder for everything and asks for the password you set; passwords and sign-ins are kept encrypted on the drive, never on the computer it runs on, and a forgotten password cannot be recovered. Everything is copied and checked before anything else happens, and only then, if you ask, are your mail and accounts removed from this computer. A copy running from a drive says so in the sidebar, can be locked or ejected from Settings, and stops writing if the drive is pulled out. It does not start at login, become the default mail app or update itself: to update it, replace the app on the drive with a newer one. Windows for now; the Mac and Linux versions say so instead of copying.
Snooze a message until you want it. Snooze moves a message into a Snoozed folder on your mail server, so it leaves the inbox on every device, and brings it back unread at the time you chose. Pick Later today, Tomorrow, This weekend, Next week or a date and time of your own, from the row menu, the selection bar, the reading pane's actions or the B key. A message in Snoozed shows when it comes back, Undo brings it straight back, and one you move out of Snoozed yourself is simply left alone. The background helper wakes snoozed mail even while MailVault is closed, if it is set to keep running. If your mail server will not keep a Snoozed folder, MailVault snoozes the message on this computer instead: it leaves your inbox here and comes back unread at the time you chose, with a notification if MailVault is open, but it stays where it is on the server, so your other devices still show it. When snooze fails for any other reason, the error now says why. Not yet available for Outlook accounts connected through Microsoft Graph.
Swipe a message to act on it. Swipe two fingers left or right across a message row on the trackpad to archive it, delete it, mark it read or unread, star it, snooze it or move it. The row follows your fingers and shows what letting go will do; stop short and nothing happens. Swiping left archives and swiping right marks read or unread until you choose otherwise in Settings > Mail preferences > Behavior, where swipes can also be turned off. Scrolling the list up and down is never mistaken for a swipe.
Search with the operators you know from Gmail. Type from:, to:, in: (inbox, sent, trash, spam, archive, anywhere, or any folder name), has:attachment, is:unread, after: and before: (as 2026-09-01 or 2026/09/01) straight into the search box, and put a minus in front of a word or a quoted phrase to leave out the messages that contain it. Values with spaces go in quotes, like from:"Ann Lee". Typed operators apply to that search only and take precedence over the filter panel, and anything MailVault does not recognise is searched for as ordinary text. Saving the search as a view keeps the sender, dates, attachments and unread operators.
Unsubscribe from a list in one click. Mail that carries an unsubscribe link shows an Unsubscribe link beside the sender in the reading pane and an Unsubscribe action in the message row's menu. It is also in the sender details in Insights, and can be added to the reading pane's actions in Settings > Appearance > Quick actions. A new Settings > Unsubscribe page lists every sender offering it that lists every sender offering one, for all accounts or one. MailVault always asks first. When the list supports one-click unsubscribe and the message passed DKIM, MailVault sends the request itself; otherwise it opens the list's unsubscribe page in your browser, or a ready-made unsubscribe email in Compose. The page also keeps a history of what you unsubscribed from.
Sender logos next to the security badge. A message that passed DMARC from a domain that enforces it shows the domain's BIMI logo beside the SPF, DKIM and DMARC shield, and right after the sender's name in the message list. Logos are fetched once per domain and kept for a week; MailVault does not check the brand certificate some logos come with.
A Blog link in Help. The Help menu and Settings > Help & Support now link to the MailVault blog, alongside the website link.
Get deleted emails back. Every email you delete is kept on this computer, out of sight, for a day, and Cmd+Z (Ctrl+Z on Windows and Linux) brings back the last one you deleted. Settings > Storage > Deleted emails lists them, with Recover to server, which puts the message back in its folder on the mail server, Recover locally, which keeps it in your vault only, and Delete now. Choose how long they are kept, from one day up to 30 days. A message moved to Trash is recovered from Trash; one deleted permanently is saved whole before it leaves the server, so deleting many messages permanently now takes longer. Outlook accounts connected through Microsoft Graph can recover locally only, and only mail already on this computer.
Compose opens at the size you left it. Resize the compose window, in the app or in its own window, and the next one opens at that size, never smaller than 200 by 200 pixels and never larger than the screen it opens on.
Changed
Archive & Delete in the bulk dialog is now a Premium feature. The one-step Archive & Delete, and the new Archive, Back up & Delete, show a Premium badge and open the upgrade prompt without a subscription. Archiving on its own and deleting from the server on its own stay free, and cleanup rules are unchanged.
The daily download limit now protects everyday mail instead of pausing it. Settings > Data usage > an account: "Pause background downloads at daily limit" (it used to read "Pause sync at daily limit") makes backups, Hoarder and download-ahead stop for the rest of the UTC day once the limit is spent, and carry on after midnight UTC. New mail keeps arriving, and opening a message always works, because those never stop for the limit. A backup that stops says "Stopped at your daily limit of 2000 MB. Continues after midnight UTC." and runs again by itself after the reset; Hoarder downloads what is left of your limit each day instead of its fixed 1,000 MB while the limit is on. On Gmail, an empty limit field now means 2,000 MB (the field shows it), which leaves room under Gmail's own 2,500 MB a day for everyday mail; the account is recognised as Gmail by its mail server, so a Google Workspace address counts too.
Hoarder is explained where you choose it. Settings > Storage > Download mode now says how much Hoarder downloads a day (about 1,000 MB per account, or what is left of your daily limit), that copies stay after mail is deleted from the server, and that Clear Cache removes them; a "Hoarder or backup?" button beside the modes compares it with Archive and backups, and the Clear Cache text says it also removes mail Hoarder downloaded.
Onboarding: pick the new email sound, and See Premium opens Premium. The Reading tab of the Appearance step offers the new email sound on a Mac (when notifications are on), and picking one plays it. On the thank-you screen, See Premium now opens Settings > Billing with your first account's address already chosen for checkout, and the welcome animation follows when you close Settings. With Premium already active, or no account added yet, the screen has a single Continue button.
Quick actions are reordered by dragging. In Settings > Appearance > Quick actions, drag an action by its handle to move it (or use the arrow keys on the handle), and remove one with the red trash button. A newly added action goes next to the actions of its kind instead of at the end; "Where new actions go" lists every action in its place. The favorite action picker has its own row, so opening it no longer moves the controls around it, and the wheel's center shows a name only while you point at an action.
Quick actions settings show your own mail. Settings > Appearance > Quick actions now draws the real message rows, selection bar and reader toolbar over the latest messages in one of your inboxes, read from this computer only, and says where each one appears. Nothing in the example acts on those messages: open its menus and wheels and try any action, and your mail stays as it was. Layout, color style, wheel layout, wheel pages and how selection buttons show are cards that each picture their option, the chosen one outlined. Before any mail is on this computer, the example uses sample messages. The quick actions step of onboarding has the same action sets, layout cards and example.
All Inboxes opens at once. Switching to All Inboxes shows the newest messages MailVault already has in memory right away, then each account's mail as soon as it is read, newest first, instead of waiting for every account. Messages that join the list fade in. With nothing to show yet, placeholder rows stand in until the first account answers.
The update window lists the commits too. Under the release notes, a scrollable list shows every commit between your version and the offered one, with a link to each on GitHub. A nightly build, whose release only says which commit it was built from, now shows what actually changed instead of "Nightly build of" and a hash.
Archive then delete only removes mail that is safely archived. Archive and delete, in bulk actions and in cleanup rules, now removes a message from the server only once your vault holds an archived copy of it; a copy that was only cached because you opened the message no longer counts as saved.
Download All asks where to save, and shows how far it has got. Saving all of a message's attachments now opens a folder picker, starting in Downloads, and puts the files in a folder named after the message inside the one you choose; cancelling saves nothing. While the files are saved, the button becomes a progress bar and the message's attachments cannot be clicked, and when it is done it says where the files went, with a Show in Folder button. Chat view now has Download All too, on a message with more than one attachment. The Download attachments button of a saved view or a search also asks where to save, and shows its progress in its place while it saves. On the Mac, MailVault keeps access to the folder you pick the same way it does for your backup location, so saving works outside Downloads too.
Settings choices look like the tabs above them. The choice buttons across Settings, from quick actions and text in Appearance to the Auto Tags rule editor, and in the appearance step of onboarding now use the same underlined style as the settings tabs. In Settings > Appearance > Quick actions, how selection buttons show is one of these choices instead of a dropdown, and the favorite action is picked from a searchable list.
Blocked trackers are shown where they were. With tracker blocking on, each removed tracking pixel leaves a highlighted "Tracker blocked" label in the message, like a suspicious link is outlined; hover it to see what was removed and why.
A friendlier Settings > Unsubscribe. Accounts are picked from a row of buttons showing how many senders each has, instead of a drop-down. Every account loads at the same time and stays loaded while Settings is open, so switching between accounts and back to All accounts is instant. Click a sender to see its mail: Settings shrinks to its bubble and the folder with that sender's newest list mail opens, searched to that sender.
Message text lines up down the whole list. The checkbox, the server and vault icon and the thread arrow now sit in one fixed column at the start of every row, so senders, subjects and previews start at the same place on every message. With preview lines on, the icons stack under the checkbox.
Closing the window quits MailVault on Windows and Linux. The close button now quits, like other mail clients there. Turn on "Keep running in the tray when closed" in Settings > Mail preferences > Behavior to keep MailVault running in the tray instead, as before. On the Mac, closing the window still keeps MailVault running.
Bug reports go to a new address. "Email the developer" in the bug report window now addresses the message to [email protected]; the old support mailbox is no longer read.
One bug report every five minutes. After opening a GitHub issue or sending the bug-report email, the Report a Bug dialog disables filing another report or emailing, and shows a countdown until they are available again, so a slow connection or a double click cannot file the same report twice. FAQ, Discussions and suggesting a feature stay open, since none of those is filing a report.
Standard logs no longer contain email addresses. Every address in MailVault's logs is replaced by its provider and a short code, like , so one address can still be followed through a log without being written in it. Who you send mail to and how long your password is are no longer logged at all. Settings > Diagnostics > Logs now shows the background helper's log too, and log files older than a week are deleted, which until now never happened.
Settings > Diagnostics > Logs can switch to Verbose. Standard stays the default and keeps addresses and subjects out of the log; Verbose writes them in full, for a support session, and applies right away without a restart.
A shorter Settings menu. Settings now has four groups, General, Accounts & import, Organize, and Vault & privacy, with Billing, Diagnostics and Help & Support kept at the bottom. Pages that belong together share one entry with tabs: Storage holds Data Usage, Privacy & security holds Security, Tracker Blocking and Encryption, Diagnostics holds Background Daemon and Logs, and Language is now a tab of Appearance. Links and search results that opened those pages still open them.
Mail deleted elsewhere disappears sooner on Fastmail, Dovecot and other servers that support QRESYNC. When a message is deleted from another device, MailVault now asks the server which messages are gone instead of listing every message in the folder again, which on a large mailbox can take close to a minute. Servers without it, Gmail among them, work as before.
Compose remembers its own window. Open a message you are writing in a new window, and every compose after it, new messages, replies and forwards alike, opens in a window of its own too. Settings > Mail preferences > Behavior > Open Compose switches back to writing over your mail.
Fixed
A signature picture now shows its resize handles. Clicking a picture in a signature selected it but drew no corner handles, so there was nothing to drag. The selected picture now has an outline and four handles, and dragging one resizes it and offers the sharper 3x file as before.
A view's unsaved-changes prompt shows the words. Leaving a view you edited without saving used to list "Contains" or "Sender" with no hint of what changed; it now shows what the phrase was and what it became, for the name, the words and the sender.
A view's words also match attachment file names. A view asking for "invoice" now finds a message whose attachment is named invoice-4471.pdf, as the word suggestions already implied, and it does the same for the search box and for excluded words. Attachment text was already searched when attachment indexing is on; file names are found wherever attachments are indexed.
Archive & Delete no longer brings deleted messages back. After Bulk Email Operations deleted messages from the server, the folder list went blank and reopening the folder showed them again as plain archived mail. The deleted messages now leave the list at once, and their saved copies are marked as deleted from the server by MailVault, the same as when you delete a single message.
Resuming a paused account migration continues the same run. Pressing Resume after Pause used to leave the paused run waiting and start a second one beside it; it now wakes the run that was paused. A pause that lands in the middle of a folder is saved right away, so it survives closing MailVault.
Saved-view counts stay true. The badge beside each view is counted again a moment after you read, star, move or delete mail, undo one of those, or a sync brings a change from another device. A count taken while the search index is still building keeps the last numbers instead of blanking them.
The Notes to Self board follows other devices. A star or read change made on another device now repaints the board's cards when MailVault syncs it, without pressing Refresh.
A view no longer shows read mail as unread. A message the view lists from your server only, with no saved copy on this computer, kept the read state it had when it was first indexed, so mail you had since read (here or on another device) stayed bold in a view. Views now take the read, starred and answered state of such messages from the server's own flags.
Closing Bulk Email Operations with nothing selected no longer leaves a "0 selected" chip. Closing the window, or unticking the last message while it is minimized, now ends the selection. A date range that matches no email says "Nothing found for this range" instead of a bare prompt.
A signature that is only a logo is no longer erased. Opening Account Settings used to save a logo-only signature as empty, so it never went out with your mail.
Undoing a star updates the Notes to Self card. Undo, Cmd+Z and a star made from the list now repaint the card and the vault copy too. Marking a note done and deleting one can be undone as well, and Cmd+Z works while Notes is open.
Saved views no longer look empty while the search index rebuilds. A view opened during indexing says it is waiting, a notice explains that views can lag until indexing finishes, and the view fills in by itself when it is done.
The Views upgrade message is readable. The free-plan limit under New view is now a clear card with an Upgrade button.
Quick actions settings keep their place. Choosing Message rows, Selection bar or Email reader no longer scrolls Settings to the top, the Menu and favorite labels no longer run over the Clear button, and the preview no longer draws the wheel over the sample rows.
Mail you send from an alias counts as yours everywhere. Only the login address and the one "Send Mail As" address were recognised as you, so a message sent from any other alias showed as a stranger's bubble in Chat, was grouped under the wrong person when sorting by sender, turned up among your contacts, landed in a "Needs reply" view and was missing from Notes to Self, and Reply All could put that alias back on the To line. Every alias of an account now counts as yours in all of those places, and in Chat, sender grouping, Reply All, contacts and Insights a Gmail address is recognised however its dots are written. The From row of a new message also shows each alias under its own name, and the message goes out with that name.
"No internet connection" no longer appears on networks that block DNS traffic. To tell whether this computer is online, MailVault connected to three public DNS servers on the DNS port only. Many company networks, VPNs and internet providers block that port, so on those networks the banner said the internet was gone, and background syncing stopped, while everything else worked. The check now also tries those servers on the port secure websites use, which is almost never blocked, and your own mail servers as well: any one of them answering means you are online. A mail provider that is down still never makes MailVault say the internet is gone, because the public servers are always asked too. Mail servers on this computer or your local network, such as the Proton Mail Bridge, are left out of the check, since they answer even when the internet is down. Every connection the check makes is listed on the Network Activity page.
A failed connection says what went wrong and what to do about it. Instead of a bare "Connection problem" under the account, MailVault now says which of these it ran into: the server name could not be found, the server refused the connection on that port, nothing answered on the server and port (which it names, so you can ask your IT team to allow it, since a firewall or VPN is the usual cause), the server's certificate could not be verified, the server rejected the sign-in, or your provider is limiting connections for now, in which case waiting a few minutes or closing other mail apps helps. For a rejected sign-in, the button under the message opens the account to enter the password or sign in again, instead of retrying. Adding an account gives the same answers, with the server's own message still shown underneath. A certificate problem while adding an account now reads properly instead of starting with "undefined".
A message read or starred on another device shows so in the open list. MailVault already knew, but the folder you were looking at kept the old read and star state until you switched folders. It now updates by itself, and in All Inboxes too, and the unread count follows.
Quick action icons show the state of the message. On a starred message the star in the row actions, the selection bar, the reading pane and the wheel is now a filled star, and on one that is not starred it is an empty one, like the star beside the sender; the old crossed-out star is gone. A lone Archive on an archived message now shows the restore icon that goes with its Unarchive label, and the reading pane's light and dark switch shows a sun or a moon for the theme it switches to. Every place that shows quick actions, Settings and onboarding included, now uses the same icon for each action.
A backup during an MBOX import no longer copies half a message. Each imported message is now written in one step, so a backup that runs while a large file is still being imported sees a whole message or none of it, and cannot keep a cut-off copy.
The message list stays responsive while MailVault builds its search index. The index now works at background priority and pauses whenever you open, delete, flag or move a message, and its progress is a small chip in the corner instead of a window that covers the list. Click the chip for details.
Importing a large MBOX file no longer runs out of memory, and imported mail shows up. MBOX import used to read the whole file into memory first, so a big Google Takeout export ran the computer out of memory. It now reads one message at a time, whatever the file's size, and the progress bar follows how much of the file has been read. Imported messages were also given numbers the mail server uses for its own messages, so the server's messages hid them in the list and could even open with an imported message's text. Imports now get numbers of their own and appear in the folder, sorted by date, next to your other mail. A file that cannot be read to the end keeps the messages imported before the problem. The import goes to the account you have open unless you pick another in the dialog, not always the first account.
Mail imported from MBOX by an earlier version now shows up, and importing a file twice no longer doubles it. An MBOX import made before this fix gave its messages numbers the mail server uses for its own mail, so they stayed hidden behind the server's messages, and the server messages with those numbers were never downloaded or backed up. When you open such a folder, MailVault now moves that imported mail to numbers of its own, in your vault and in your backup folder, so it appears in the list, and the messages it was hiding are downloaded and backed up again. Nothing is deleted: an imported copy of a message the server already has is set aside instead of being shown twice. Importing an MBOX file whose messages the folder already has, in your vault or on the server, skips them, and the message at the end says how many were skipped.
Onboarding no longer jumps around. The Appearance step kept moving as you switched between Colors, Layout, Reading and Quick actions or changed a choice; each step now starts at the top and grows downward. The thank-you screen no longer scrolls sideways while its hearts fly, and the welcome animation no longer shakes while the envelopes land. Its choice buttons no longer split a word across two lines (Expandable under Conversations, and longer labels in other languages): a choice that does not fit moves to the next row.
An account's unread count updates as soon as its mail arrives. New mail shown straight away in All Inboxes left the unread badge of the account it arrived in at the old number until the next scheduled check. The count now follows every change the helper picks up, a message read on another device included.
Reply starts on the first line. Reply and Reply all opened with the cursor after your signature; it now starts on the first line, above it.
The star button in the reading pane shows what it will do. Once a message is starred, the button shows the unstar icon, not the star it already has.
The wheel's Mark read icon matches its label. The read toggle in the quick actions wheel always showed an open envelope, even when it said Mark unread. A conversation now offers Mark read and Mark unread side by side.
Report on GitHub is always available. The five-minute wait after a bug report now applies to emailing the developer only; opening GitHub never starts it or waits for it.
Unstarring from the Starred view works. Clicking the star of a starred message in a saved view, such as Starred, said "Starred 1 message" and left the star on. It now removes the star and says so. The message stays in the view, unstarred, until the view reloads, so a star taken off by mistake can be put back.
Sent and Trash on servers that keep every folder under Inbox. On mail servers that refuse folders at the top level ("NAME NOT ALLOWED"), MailVault now creates Sent, Trash and Snoozed inside Inbox instead of failing.
The original message in a reply or forward respects tracker blocking. The quoted original shown while replying or forwarding, and its pop-out window, loaded remote images and tracking beacons even with tracker blocking on, unlike the reading pane. It now strips them the same way the reading pane does.
A folder with subfolders keeps its own list. Opening a folder that has folders under it lists every message in the branch. MailVault then tried to download all of them from the top folder alone, where most of them are not, and saved the whole branch as that one folder's list of messages. It now downloads only the top folder's own messages ahead of time, fetches the others from their own folders when you open them, and leaves the top folder's list as it is.
A folder with subfolders keeps the right message count. A message deleted from the top folder, or found gone from it, could take one off the count shown for the whole branch even when that message was not in the list.
Chat view opens the right attachment in All inboxes. In chat view, opening or saving an attachment of a message from another account than the one selected in the sidebar could read the selected account's copy instead, and with two messages sharing a number that meant the wrong file. Attachments now always come from the message's own account and folder.
Settings opens before you add an account. Choosing Settings from the menu on the welcome screen or during onboarding did nothing; it now opens Settings there too.
The tray icon shows on Linux. It was a black glyph meant for the macOS menu bar, which disappeared against the dark GNOME top bar; Linux now uses the app icon, as Windows already did.
The snap keeps your sign-ins without any setup. The snap now stores account passwords and sign-in tokens through the desktop's Secret portal, in an encrypted file inside its own data folder, instead of asking for access to the whole system keyring, which snaps do not get automatically. Adding an account works straight after installing. Sign-ins saved by an earlier snap you had connected to the keyring by hand are moved over the first time they are read. On a desktop without the Secret portal, the snap falls back to the system keyring and says to run sudo snap connect mailvault:password-manager-service if that is not allowed.
The Linux snap starts on up-to-date systems. On Ubuntu 26.04, Debian 13 and similar systems the snap could stop at launch with "did not find extension DRI_Mesa version 1". It carried an older copy of the graphics libraries that clashed with the GNOME platform snap it runs on; it now uses the platform's copy only, which also makes the download smaller.
Reset view only shows when there is something to reset. Switching a saved view between list and explorer, its grouping or its timeline and then back to how it was saved no longer leaves the Reset view button behind.
All inboxes threads show the replies you sent. In threads view, All inboxes now joins your sent replies to their conversations the way a single account's inbox does, for every account at once: in grouped and expandable rows, in the thread's message count, in the reading pane and in the chat view. A reply sent from an account other than the one open in the sidebar no longer disappears from its thread a moment after sending.
A message opened from search shows everything it shows in its folder. The SPF, DKIM and DMARC shield, the warnings for a look-alike sender name, a Reply-To going elsewhere, suspicious links and trackers, and the Unsubscribe link were missing from search results and from a message opened from them. The sender info button now always opens, counting the search results and the open message too, where before it showed nothing for a sender outside the open folder. After updating, MailVault asks once whether to rebuild the search index, so mail indexed by the previous version shows them in search results and among archived messages in the list too; saying no changes nothing, and the rebuild is also in Settings > Search index.
No more in message previews. Invisible padding that some newsletters put after their teaser text showed up as a run of in the list's preview lines.
Every folder the server lists shows up, and opens with its mail. A folder whose name contains a backslash or a quote, such as a Gmail label created by another mail app, opened empty; it now opens with its messages. A folder that is only named like Trash or Archive, such as Gmail's [Imap]/Trash, now stays under its own parent instead of being moved to the top, and only the folders the server itself marks as Sent, Drafts, Trash, Junk or Archive are moved there and used for deleting and sending. Two folders that would end up with the same name are both shown instead of one disappearing, and an empty [Gmail] container is no longer listed.
Search results show preview lines. With preview lines turned on, search results and saved views now show the start of each message like the rest of the list. The Appearance sample is long enough to show the difference between one, two and three lines.
The read or unread button shows the right envelope. In the reading pane and the full view, the button's icon now changes with the message, so it always shows what clicking it will do.
Undo brings a deleted email back at once. The email is back in the list the moment you click Undo; moving it back on the server happens afterwards, and if that fails the email leaves the list again and MailVault says why.
Deleting, undoing and deleting an email again no longer leaves it in All Inboxes. It used to show up in All Inboxes while also sitting in Trash.
Deleting keeps every view in step. Deleting an email in All Inboxes now closes it if it was open, and the message count and unread badge change straight away; the account's own inbox agrees without a reload, and so does All Inboxes when you delete from an inbox.
Retry on a connection problem waits for the answer. Clicking Retry hides the notice while MailVault reconnects, shows it again only if that fails, and cannot be clicked twice. In All Inboxes, Retry now actually reconnects the account instead of doing nothing.
Restore and folder names can no longer reach outside the mail vault. A malformed account id or a folder named .. could point a restore, import or vault read at a directory outside the account's own mail. Such names are now kept inside the vault, and restore refuses them outright. Thanks to kta1kri for reporting it.
Replies you send keep their "Original Message" header in view. The header naming who wrote the quoted message now sits above the quote instead of inside it, so a mail app that folds the quote, MailVault included, still shows it.
Your own sent mail is recognised in every provider's Sent folder. In Gmail's "Sent Mail", Outlook's "Sent Items" and other Sent folders not named exactly "Sent", your own message offered Reply, Reply All and quick replies as if someone else had written it. It is now treated as sent mail wherever it is filed.
A reply shows its text and one quote toggle. A reply from Gmail, and some from Thunderbird and Outlook, could show two quote toggles side by side, hide the line naming who wrote the quoted message, or, when the reply was all quote, show nothing but the toggles. Each quote now folds under one toggle below its "wrote:" line, and a message that would fold down to nothing is shown in full.
MailVault gives memory back on the Mac once a large mailbox has loaded. After loading a big folder, MailVault and its background helper kept the memory they had just used and freed for minutes, so Activity Monitor showed them at their peak. After syncing a 10,000-message inbox, the helper now sits at about 15 MB instead of 107 MB and the app itself at about 26 MB instead of 84 MB.
Opening MailVault no longer announces mail you were already told about. When the background helper kept running while MailVault was closed, the next launch showed a burst of new-mail notifications for mail that had arrived hours earlier, often the same message several times. Mail that came in while MailVault was closed is still announced, with one notification per folder that counts it all.
MailVault stops drawing while it is in the tray or minimized on Windows. A hidden or minimized window kept rendering its page as if it were on screen, so any animation on it kept the processor and graphics card busy for as long as MailVault stayed out of sight. The page now rests until you open the window again, as it already did on the Mac.
A view saved from a search keeps the search's last day. A search that ends on a date includes that whole day, but the view saved from it stopped at midnight and left that day's mail out.
New mail shows up the moment it arrives. A Gmail account no longer drops its live connection every hour when its sign-in is refreshed, and after any dropped connection (a Wi-Fi blip, a restarted helper) MailVault now fetches the mail that came in meanwhile instead of waiting for the next scheduled refresh or a restart of the app. On a large inbox a new message is shown before MailVault finishes checking the rest of the folder, and its body is downloaded straight away, so it opens at once, reads offline and turns up in search. All Inboxes now updates on the scheduled refresh too, and whenever mail arrives in any of its accounts.
Threads follow your mark-as-read setting. Opening a thread used to leave its messages unread whatever Settings said. Now each unread message you have open in a thread is marked read on its own, right away or after your delay, and folding one before the delay runs out keeps it unread. Mail that arrives while the thread is open stays folded and unread until you open it. In the chat view, every unread message of the conversation you are reading is marked after the delay.
A message marked read by the reading timer now shows as read in the list. If you moved to the next message, closed the reader or opened a thread while the timer's change was reaching the server, the message was read on the server but stayed bold in the list, in a search and in a saved view. Every row now follows. A message from another account or folder opened from a saved view is also opened, and marked, in its own account instead of the one you were in.
A new-mail notification names the message that just arrived. When a message came in with a date older than mail you already had, such as a forwarded or migrated copy or a sender whose clock is wrong, the notification showed the sender and subject of an older message instead.
Changing From changes the signature too. Since 2.16.0, picking another account in From left the signature of the account you started with in the message. The new account's signature now replaces it, and whatever you have written stays as it is.
Compose opens at its usual size again. Since 2.16.0 a new message filled the whole width of the window. It opens at its usual width again, and its corner still lets you make it as large as the window.
The row menu offers "Delete everywhere" only when there is more than the server copy. On a message that is only on your mail server it was shown greyed out, under a name that promised to clear your vault and backup as well.
Setting the read state yourself keeps the message where it is. Marking the open message unread no longer has the reading timer mark it read again a moment later, the thread reader shows the new state straight away, and with the Unread filter on in the explorer the message you are reading, and the ones you read since turning the filter on, stay on screen.
Opening a message on a throttled Gmail account no longer takes 20-40 seconds. A pooled connection that was simply slow to answer was treated as dead and replaced with a fresh login every time; it is now given enough time to answer before MailVault gives up on it.
Opening a message no longer waits behind a bulk archive, a cleanup rule or snoozed mail waking up. These took the connections kept for the message you click, so opening one while they ran could take as long as several whole downloads. They now use the connections kept for background work, while saving a message you picked yourself or unsnoozing one right away still goes first.
Two copies of MailVault on one Gmail account no longer get the account slowed down. Gmail allows 15 connections to an account at once, and two MailVault installs (a second computer, a portable copy, a backup) could open more than that between them, after which Google answered every request in about 10 seconds for hours. MailVault now keeps at most seven connections open per account, closing an unused one when it needs room, so two installs and a phone fit.
A connection that went silent no longer holds a message up for 45 seconds. When a kept-open connection to the mail server had quietly died, opening a message waited for the full timeout before failing. MailVault now gives up on a connection after 15 seconds without a reply and fetches the message on a fresh one, and a server that stops answering while connecting (looking up its address, securing the connection, greeting or signing in) is given up on too instead of being waited on indefinitely.
A message the server no longer has is no longer fetched over and over. Background loading kept retrying a deleted message forever, up to dozens of times a day on a busy account, each one paying the full cost of a slow fetch; the row is now dropped from the list instead.
A message that timed out or hit a dropped connection while opening now retries once on its own. Most of the time it simply opens on the second try instead of showing an error, while a message the server has confirmed is gone is never retried.
Adding a Google account no longer fails with "the server did not answer in time" on a slow connection. Testing the connection now retries once if the first attempt stalls, and no longer waits on a slow sign-out after the test has already succeeded.
Signing in with Google or Microsoft now finishes adding the account on its own. After you complete sign-in in the browser and return to MailVault, the account is added right away, with no extra click on Add Account needed; that button is still there if the automatic add fails. If you sign in to a different Google account than the address you typed, MailVault now says so and does not add it.
The radial quick-actions wheel opens and reacts instantly, especially on Windows. Right-clicking a message opened the wheel only after the button was released, and moving between its actions could feel sluggish. It now opens the moment the button goes down, and moving between actions no longer redraws the whole wheel.
The row menu and reading pane show only the read, star and archive actions that apply. Mark as read, mark as unread, star, unstar, archive and unarchive used to stay in the menu greyed out once they no longer applied; they are left out instead. Right-clicking inside a multi-message selection shows both sides of a pair when the messages are a mix of read and unread, starred and not, or archived and not.
Open in window works for plain-text messages. The reading pane's Open in window did nothing for a message with no formatted version, only text; it now opens that text in its own window.
Reply puts the cursor in the message body. Reply and Reply all used to leave the cursor in the To field, which already has a recipient, so nothing typed there went where it should. New messages and forwards still start in To, since a forward has no recipients yet. A reply started from the row's radial quick-actions wheel also opens right away instead of waiting on the message to finish loading, with the quoted text filling in a moment later. When Compose opens in a window of its own, it waits for the message instead, so the window has the quoted text.
v2.16.0September 25, 2026
Added
MailVault for Windows. MailVault now runs on 64-bit Windows, from a signed installer on the download page. Passwords are kept in Windows Credential Manager, MailVault sits in the notification area and can be made your default mail app, and a backup made on a Mac can be imported. Settings > Mail preferences > Behavior has a Check for updates button, since Windows has no app menu to hold one, and the same Stable or Nightly choice as on the Mac; MailVault also checks once a day while it stays open. A nightly build follows nightlies unless you pick Stable, and it is only replaced by a stable release newer than itself.
Jump to any month in your mail. The message list now marks where each month begins, keeps the month you are reading pinned at the top, and shows a large date beside the scroll bar while you scroll. Move the pointer to the list's right edge for a timeline of years and months: click or drag to go straight there, including to months that have not been loaded yet, which MailVault pages in for you. The timeline also works from the keyboard.
Send it later, in the time zone you mean. Compose can schedule a message for a date and time in a zone you choose, and MailVault keeps the finished message in your vault until then. Date and time are one picker, the time zone list can be searched by city or UTC offset, and MailVault suggests the recipient's zone from their last email or from the zone you last scheduled for them. Scheduled mail has its own place in the sidebar: click a message there to edit it, and it stays scheduled as it was until you save the change. You can also move it to another time, send it now or cancel it. The wall clock you picked is what is stored, not the instant it happens to mean today, so a daylight-saving change between now and then does not move your send. The Scheduled folder explains when mail goes out while MailVault is closed and links to the setting for it; with the background helper off, a scheduled message goes out the next time MailVault runs. The arrow next to Send opens one panel with two tabs: Send in, where you type or step hours and minutes (up to 24 hours), and Date & time for a set moment. Schedule there sets Send up without sending: the button turns into Schedule send, and next to it the footer says when the email goes, with an x to go back to sending now. Delays longer than five minutes, set times, editing and rescheduling are part of Premium, and are kept if MailVault quits. Delays of up to five minutes stay free and can be undone, and sending now or cancelling what is already scheduled works on any plan.
Notifications decide by rule, and tell you which rule. Quiet hours per account, a list of people whose mail always reaches you, and mutes for an account or a folder, applied in an order that means an important sender still gets through a muted account. Settings shows the last two hundred decisions with the reason for each, so a notification that never arrived can be accounted for instead of guessed at.
Reply starters under a conversation. MailVault offers a few editable openings under the newest message of a person-to-person thread, and stays quiet on newsletters and automated mail. A click opens Compose with the text in it, ready to change. Nothing is ever sent for you.
Writing help that runs on your Mac. Draft a reply, shorten it, change its tone, pull out the action items, or summarise a thread. MailVault starts on Apple's on-device model where the Mac has one, or a model you have downloaded, and shows you the exact text before anything is used. You can point it at a model of your own instead, and until you do, nothing leaves your machine. Everything it produces lands in the editor as a draft you can rewrite or undo, and no action sends mail.
Tagging rules written in plain words. Describe what a rule should catch, add the exact conditions that must also hold, and MailVault tags matching mail as it arrives, keeping it in the Inbox or out of it as you prefer. A rule can be previewed against mail you already have before it is switched on, applied to your history in one bounded pass, and that pass can be undone. Rules are answered on your Mac unless you explicitly point one at a provider of your own.
Keep MailVault syncing when it is closed. Settings โ Background Daemon has a switch that keeps the background helper running after you quit, and opens MailVault again when you log in, so mail keeps syncing and scheduled messages go out without the window open. On macOS this registers a proper login item, which the first time may wait for your approval in System Settings โ General โ Login Items. On Linux it adds a startup entry; the Snap build manages startup itself and says so instead of offering the switch.
MailVault tells you when it needs the keychain unlocked. If the background helper cannot read your passwords because the keychain is locked or macOS is waiting for your permission, MailVault shows a card in the corner with an Unlock button until the keychain can be read again, and posts a notification when its window is not in front. The helper checks for itself every few seconds, so unlocking the keychain any other way works too. Scheduled mail waits instead of failing, and goes out once the keychain is unlocked.
Fields of your own on any message. Add the columns your mail actually needs โ Owner, Priority, Needs invoice, a due date, a tick box โ and fill them in from the reading pane. A field belongs to one account or to all of them, and one account's schema can be copied into another. A choice list can be added to, renamed, reordered, or trimmed โ and removing a choice tells you first how many messages are holding it. Each choice can be given a colour, which the reading pane shows beside the answer, and the fields themselves can be moved up and down into the order you want to read them in. Fields can be searched (field:Priority=High, or field:Priority for anything with an answer) and used to build a saved view. Like tags, they are stored on your Mac: nothing is written into the message and nothing is sent to your mail server.
Saved views: your own inboxes, made of filters. A view is a name and a set of filters โ tags, attachments, starred, unread, sender, dates, folders, free text โ evaluated across every account, or only the ones you pick, and shown in the message list. Nothing is moved or copied: a message can appear in as many views as you like and still live in exactly one folder. Views sit at the top of the sidebar, above your accounts, and MailVault ships three: Needs reply, Starred and Attachments. A view can also group what it finds โ by sender, by date, or by one of your own fields โ and a filter on a field can ask for more than a match: is not, has any value, is empty, and before or after a date. Any search you can run can be saved as a view from the search bar. Views are built on their own page in Settings, where a builder shows what a definition would find while you are still typing it, so you can see a filter working before you keep it. The sidebar opens views and nothing else: a filter cannot be rewritten from under the list you are reading. The section folds away when you want the room, a + beside it makes a view the way the + beside your accounts adds an account, and opening a view lets go of the account and folder you were in, because the list shows one or the other. A free MailVault keeps three views, the three it ships with included; a paid one keeps as many as you like.
Tags you can put on any message, on any provider. A message can carry as many tags as you like, independently of the folder it sits in, and they work the same on a server that has no labels of its own. Tag one message from its row or the reading pane, or a whole selection at once, and narrow a search with tag:receipts (tag:"needs reply" for a name with a space). Tags are stored locally and never change your mail: nothing is written to the message file and nothing is sent to your server.
Keep the conversation beside your reply. Compose has a remembered toggle for reading the original message, or the thread you replied from, beside the message you are writing.
You can turn off the confirmation that appears when you delete. Settings โ Mail preferences โ Behavior โ Deleting, and the Reading tab of first-time setup, choose between asking every time (the default) and deleting on the click. Delete everywhere, and removing a message the vault holds the only copy of, still ask: neither can be undone.
Settings now lists the server actions MailVault still owes. Background Daemon shows every delete, move or flag change your server has not accepted yet, with the reason it last failed, a Retry now button, and a Cancel for one that has been failing for too long.
Search terms are highlighted in the message you open. Opening a result now marks every occurrence of what you searched for inside the message body, in the reading pane, in a thread and in the full-window view. The highlight follows the query while you refine it.
A result that only matched inside an attachment says so. When the term is in an attached file and not in the message itself, the row's paperclip is highlighted instead of leaving you hunting for text that was never in the body.
Attachments show themselves instead of a paper icon. Attached images appear as their own thumbnail in the message; everything else gets the icon of its kind, so a zip, a spreadsheet and a video are no longer three copies of the same picture.
Save As sits on every attachment. It used to be right-click only, which meant it could not be reached from the keyboard at all.
Drag an attachment out to the Desktop or any app. Dragging a row hands over the real file, not a web link to it.
Move accounts to another computer. Export accounts, passwords and settings to an encrypted, password-protected file and import it in MailVault elsewhere (Settings > Accounts). A new install can import straight from the welcome screen. Accounts the other computer already has are left as they are, and a forgotten file password cannot be recovered. Any imported tagging rules arrive turned off, so you can review them before they run.
Choose where Compose opens. Settings > Mail preferences > Behavior, and the mail step of first-time setup, choose between writing over your mail (the default) and always opening Compose in a window of its own.
Skip first-time setup, and pick it up later. Every step of setup now has Skip tour. After skipping, a card in the corner offers to carry on from the step you left, until you finish it or tick "Don't show this again".
Run writing help without the review step. Settings > AI can turn off the "Review before sending" dialog for AI actions. A custom endpoint is still reviewed the first time it is used.
Switch a saved view between List and Explorer. A view that groups its mail can now be read as a plain list, and any view can change its grouping or timeline. Each view keeps the layout you last left it in when you come back from another view or folder, and Reset view returns it to how it was saved.
Pick an emoji for a view. Clicking the emoji box in the view editor offers a set of emojis to choose from. Typing any other emoji still works.
Search a view for one set of words OR another. The view editor's Contains field now holds boxes of words: every word in a box must appear, and mail matches if any box matches, so (jasinskio && 14a-37) || (mindaugo 30) is two boxes. Type || or press OR to start a new box, and drag words, or the OR button itself, to regroup them. A phrase such as "mindaugo 30" now stays one word and must match whole, and a two-character word joined with &&, such as mindaugo && 30, is also found in the message text, so "Mindaugo g. 30" matches.
Download every attachment a view finds. A view that filters on attachments, and a search with the Has attachments filter on, now has a Download attachments button at the top of the list. It saves the attachments into one folder in Downloads; signature logos and tracking pixels are left out. When the view's time range spans two months, such as the last 30 days, a wheel lets you download all of it, this month, or last month.
Calendar time ranges for views. Besides the last 7, 30, 90 and 365 days, a view can cover this month, last month, this year or last year. They follow the calendar, so "Last month" in October is September.
Filter a view by several senders. The Sender field now holds boxes like the Contains field: names in one box must all match the sender, and mail matches if any box matches, so acme || [email protected] shows mail from either.
A new view opens with an empty name. The name field shows "New view" as a hint and has the cursor, so you can type the name straight away. Leaving it empty keeps "New view".
A view can open with its timeline shown. The view editor has a Show timeline toggle, saved with the view. The Timeline button in the list toolbar still overrides it for the session, and closing the view leaves your default timeline setting untouched.
Edit, open and remove links while you write. The link button in Compose now opens a small panel for the link's text and address, and pressing it with the cursor in a link edits that link. Pointing at a link shows Open link, Edit, Remove link and Remove link and text. This works in a Compose window of its own too.
Changed
The labels you had already made are now tags. They move across on the first start, keeping the messages they were on wherever MailVault can still recognise the message. A label MailVault cannot place is left behind rather than guessed at, and a quick action set to apply one keeps working. Unlike the old labels, a tag stays with its message when the message is moved to another folder.
MailVault keeps its own state in a database instead of loose JSON files. Where the vault is, the folders it can reach, your transfer counters, the classification model and the list of server actions still owed all move into two SQLite stores the first time this version starts. The old files are renamed rather than deleted, so nothing is thrown away, and cached message headers now live beside your custody records instead of one small file per message.
The message list holds less in memory. Moving between folders keeps fewer of them in memory at once. Messages downloaded in the background are saved to your vault without also being held in memory, and opening one reads it from the vault. Deleting, moving or purging messages no longer sends the folder's whole list back through the app, and checking for new mail no longer loads every stored header of each account to find what is new.
Folders open, and messages archive, faster on large vaults. Which messages your vault holds, and the previews shown for them, now come from a small database the background helper keeps up to date, instead of a fresh listing of the folder and a read of every saved message each time. A message's inline images load in one read, and removing many messages from the vault at once takes one step per folder instead of one per message.
New installs play the Glass sound for new mail. Existing notification settings are kept.
Right-click a message for its quick actions. Right-clicking a row in the message list opens the same quick actions as the row's own menu, at the pointer and in the layout you chose for them, radial menu included. It replaces the browser menu that only offered to reload the window.
The List and Explorer switch stays put. It now sits at the right edge of the message list toolbar in both modes, with the Timeline button moved to its left, so switching to Explorer no longer slides it across the toolbar.
Setup walks you through every look option. On the "Make it yours" step of first-time setup, Next is now the main button and moves through Colors, Layout, Reading and Quick actions in turn. Continue appears once you reach Quick actions, so no tab is skipped by accident. The tabs can still be clicked directly.
First-time setup starts from the recommended look. A new install begins with the Graphite palette, threads that expand in place, and a colored radial menu for the quick actions on message rows, with the selection bar and reading pane actions inline and in color. Settings you have already chosen are kept.
Fixed
Typing after a link no longer adds to the link. Text typed right after a pasted or inserted link became part of it, space included. It is now plain text.
A sent email no longer shows up twice. After a send, the conversation and the Sent folder could show two copies of the same email, one marked "Only copy", when the server was slow to file it in Sent. The email now goes out under the same Message-ID as the copy MailVault keeps, and the extra copy is also cleared when a slow server files the email after MailVault stopped waiting for it.
Two delayed sends in a row both go out. Sending a second email while the first was still in its send delay replaced the first: it never went, and the second could go out early. Each email now keeps its own countdown, and Undo takes back only the one on screen.
The green SPF/DKIM shield is back on opened messages. Opening a message showed no sender verification shield, even for mail that passed SPF and DKIM, because the opened copy did not keep the authentication results the message list already had. The shield and its details now show again.
Quit in the tray menu stops the background helper again. Since 2.10.0, choosing Quit from the tray menu (or File, Quit on Linux) closed MailVault but left its background helper running. It now stops, unless Settings, Background Daemon is set to keep it running after you quit.
A restored backup now brings back each account's server. Backup ZIPs recorded every account's incoming and outgoing mail server as empty, so an account recreated by Import Backup came back with no server at all. New backups keep both, and restoring one fills them in. Backups made before this fix still import, but they never recorded a server, so their accounts still come back without one.
Numbers follow the language you chose for MailVault. Counts in the message list, the sidebar, progress dialogs and Settings were grouped the way your computer's region writes numbers, so English MailVault on a Lithuanian or German Mac showed "12 345" or "12.345". They now use the app's own language, the same way sorting already did.
Tracker blocking now covers Cleanup and Time Capsule. Opening a message in the Cleanup preview or in a Time Capsule snapshot loaded its tracking pixels even with tracker blocking on, because those previews skipped the protection the reading pane applies. They now show the same cleaned message as the reading pane.
An attachment's name can no longer run commands on your Mac. Choosing Open With on an attachment whose name was built to break out of the old AppleScript could run a shell command as you. The app is now picked in the standard macOS panel and the file is handed to it directly, so a name is only ever a name, including names with accents or other non-English letters. The sign-in page shown after a failed Microsoft or Google login also stops rendering whatever markup was passed to it. Thanks to Lukas Heichel for the report.
Download keeps every attachment inside your Downloads folder. An attachment whose name was made to point at another folder could be written outside Downloads when you clicked Download. Only the file's own name is used now.
A message deleted in another email client stops haunting All Inboxes. Its row used to come back every time the view repainted, and every click on it failed, because the removal was only ever written down in a single-folder view. The reading pane also stops calling it a failed load: when the server has proved the message is gone it now says it was removed elsewhere, instead of offering a retry that cannot succeed.
A deleted message no longer leaves its tags behind. Tags and field values were kept for messages that no longer existed anywhere, and the count beside a tag counted them. They are forgotten when the last copy of a message goes โ and only then, so moving a message between folders still keeps everything you put on it.
Unfinished messages return as draft bubbles after a restart. Compose keeps the message, attachments, sending identity and reply context so you can continue where you left off.
Reply quotes the text you selected. Selecting part of a message before Reply or Reply All quotes that passage. Without a selection, the whole original is quoted as before.
Tab from Subject goes straight to the message editor. Formatting controls remain available from the keyboard.
Switching accounts keeps the email-list header steady. Loading, empty folders and changing counts no longer move the list controls up and down.
New mail notifications no longer announce the whole mailbox. A refresh counted every message it had not yet loaded as an arrival, so a folder with more messages than the list had room for produced banners like "1134 new emails" that named mail from years ago. Only messages the cache genuinely did not hold are counted, and nothing is announced while a folder is still being downloaded for the first time.
Notification banners name the sender instead of "[object Object]". Every multi-message notification body started with that placeholder where the sender's name belonged.
A message you open from a search result is marked read. Opening a message whose body MailVault already had on disk, which is what a search result usually is, never started the mark-as-read delay and never marked it read. It only marked itself if you closed it and opened it again. The result row now updates as soon as the message is marked, instead of staying bold until the search was run again.
Search on large vaults is back to milliseconds. Marking attachment-only hits made every search re-probe the index once per row, which took a fifth of a second to half a second on a 50,000-message vault. It is back to a few milliseconds.
A delete the server refuses is retried instead of quietly coming back. A failed delete used to put the row back on the list and forget the whole thing, so a dead connection was enough to undo a delete you had confirmed. It is now re-sent straight away, and if that fails too it stays queued and is retried on reconnect, every few minutes, and at the next launch.
Mail that arrives while you are looking at a folder cannot go missing. The background helper decides what to fetch from the last message number it has seen, and the app wrote that number too: refresh a folder that had more new mail than one page holds, and the helper was told everything up to the newest one had been dealt with, so the messages in between were never fetched by either side. Read and starred marks changed on another device could go the same way. The helper now keeps its own place in the folder, and mail the app has already put on screen is not announced a second time.
A message deleted from another device leaves the list straight away. Deleting mail in a webmail tab or on a phone left its row in MailVault, clickable and failing, for up to six hours. The background helper spots a message that has left the server by comparing the count it last saw itself against the one the server reports now, and that comparison was reading a number the app also writes: when the app refreshed the same folder first, the sum came out even with the deleted message still listed, and only a six-hourly full check would have caught it. The helper now keeps its own count, notices straight away when it is holding more messages than the server says exist, and retries the check on the next refresh when a folder listing fails instead of treating it as settled.
Deleting a search result takes it out of the results straight away. A message deleted from a result list stayed on screen, still clickable, until the search was run again. It now disappears the moment it is deleted, the same way a moved message already did.
Marking the open message unread no longer closes it. Only deleting it, moving it, or closing the reader yourself takes a message off the screen now.
A message you read with the unread filter on stays in the list. Opening an unread message marks it read, which took its row out of the filtered list the moment you moved to the next one. Messages read while the filter is on now stay on screen until you switch the filter off and on again.
Refreshing the list no longer closes the message you are reading. Refresh, the automatic reconnect and the periodic sync all closed the reading pane, in a single folder and in All Inboxes. Only moving to another account or folder does now.
Download All puts the files in a folder you can find. It wrote them into MailVault's own cache, where nothing pointed you. They now go into a new folder under Downloads named after the message, and that folder opens when the export finishes. A folder of that name already there is left alone and a second one is made beside it.
Attachments download straight to your Downloads folder. The Download button used to put the file in MailVault's own cache, so saving it where you expected still needed a right-click and a save dialog. It goes to Downloads on the first click, and a file already there with the same name is never overwritten.
Select messages selects the search results while you are searching. It opened the date-range picker for the whole mailbox instead, which could not see the search at all.
Search results you tick can be deleted and marked read again. Delete from server, Delete everywhere and Mark read/unread were greyed out for a message found only by search, because the selection bar could not match it to a loaded row.
Archiving a message someone already deleted elsewhere no longer fails with a code. Copying a message into the vault whose server copy had been deleted from another client reported "Could not copy that email into your vault. Nothing was removed from the server", with a raw error code after it, and left the stale row in the list to fail again on the next click. The row now leaves the list, the same way it already did when you opened the message.
A selection made while a delete, purge or move is still running is no longer cleared. Ticking more rows while a bulk action was talking to the server wiped those ticks when it finished, so they had to be made again. Only the rows the action actually handled are now cleared.
A failed search, the Cleanup and Time Capsule previews, and Mailbox Explorer show the right text again. A failed search showed a raw translation key instead of a message. The message previews in Cleanup settings and Time Capsule ignored the height they were given and stayed small. "All messages" at the top of Mailbox Explorer stayed in English in every language.
A message the server no longer holds cannot slip back into a folder you open. When reading the folder from your Mac was slow, an old cached row could land after the server had already confirmed the list, and stay there as if the server still held it.
v2.15.0September 20, 2026
Added
Search stays with the account and folder you are looking at. Locally indexed matches appear first while the background service searches server mailboxes and any uncovered local folders; changing the current account or folder cancels the old search, and one failed folder no longer hides successful results. A temporary IMAP connection failure is retried once. Premium users can choose a saved concurrency level from 1 to 5; signing out does not erase that preference.
You can delete the search index and build it again. Settings โ Storage โ Search index has Delete search index. It shows the index size, and search keeps working (just slower) while the index is off. Build search index starts a fresh one.
A big index build shows its progress. The first build, a rebuild, or 500+ new messages open a small window with a progress bar and the index size. Hide shrinks it to a chip in the bottom-right corner. It never opens while you are typing, and it closes when the build finishes. If MailVault quits or its background service stops mid-build, the build picks up where it stopped.
Fixed
Mail shows up right after MailVault starts. On a vault that still holds older cache files, MailVault's background service moved them into its new database before it would accept a single request. On a large vault that took minutes, during which the mail list spun with nothing in it and Settings reported the background helper as not running even though it was running. The move now happens in the background, one folder at a time, and it is done once instead of repeating on every start.
A busy background service no longer slows the window down. MailVault's background service now answers the app from a thread of its own, separate from syncing, classification, restores and backups. The disk work those jobs do โ writing a folder's cached message list, scanning a folder, reading every cached header before a reclassification โ has moved off the threads that answer the app as well. A large sync, a backfill or a reclassification pass can no longer make opening a folder wait.
Search repairs its local index after structural damage and keeps indexed searches responsive on large vaults. The background worker rebuilds only the derived search-index files when the SQLite schema or contents cannot be read, and keeps locked or inaccessible files for a later retry. Indexed search now follows the saved mailbox concurrency in SQL batches while keeping the same newest results.
Opening a big folder no longer freezes the window. Mail files, cache files and the local search index are now all read and written by MailVault's background service instead of the app window itself, so scrolling, typing and switching folders keep working while a large folder loads or a bulk change is being saved.
Archiving and bulk deleting no longer freeze the window either. Both now run in MailVault's background service too, so scrolling, typing and switching folders keep working while a large archive or bulk delete is in progress.
Cancelling an archive no longer stops an unrelated bulk delete. If an automatic archive and a manual bulk delete happened to be running at the same time, cancelling one could silently stop the other. Each now has its own cancel.
Mail Insights is now as consistent as the rest of your mail data. It reads through MailVault's background service too, the same way mail files and search do.
Outlook message numbers can no longer collide. MailVault's background service and its backup could assign the same internal number to a new Outlook message at the same moment. Assigning a number now takes a lock both share.
An account's backup card shows its stored size again. Settings โ Backup, each account's card always showed "--" for Storage instead of the size on disk.
A message imported through Import MBOX stays in the list and survives Clear cached emails. A message brought in through Import MBOX was saved without MailVault's archived marker, so a later Clear cached emails run could remove it, the same gap the backup-mirror restore had before 2.14.0. Imported messages are now marked archived, so they stay in your vault the way anything else you've explicitly saved does.
Import, export, mailbox migration and restoring emails to the server are now as consistent as the rest of your mail data. They all run in MailVault's background service too, the same way mail files, search, archiving and Insights already do.
v2.14.0September 15, 2026
Added
Clicking a new-mail notification opens that email. On macOS, clicking the banner brings MailVault forward in the account and folder the message arrived in and opens the message it showed. With message previews turned off, the banner names no message, so the click opens the folder instead. A notification held back during a focus session keeps its message when it is delivered afterwards.
Fixed
Thread messages keep their spacing after a reply. Sending a reply could leave the conversation's sender details and previews overlapping when the temporary sent copy was replaced by the server's copy. The reader now keeps existing message heights through the refresh.
Search lists each message once. A message saved in more than one folder, such as a Gmail message archived from the inbox and backed up from another label, showed up as two identical results with two different save states. Search now shows it once, with the save state of the copy in the folder you are viewing.
A message MailVault cannot read no longer stops the folder it is in. iCloud sometimes describes a message in a form MailVault's reader does not understand. Every such message used to end the connection, so the folder showed Connection problem and nothing loaded; a retry skipped at most three of them, forgot them when the app restarted, and the Inbox filled a few messages at a time. MailVault now reads past the message it cannot understand and shows every other one in the same pass, over the same connection. The unreadable message is still left out, and its description is written to the daemon log so a report can carry it.
Compose opens the first time you ask. The first compose window after MailVault started, whether a reply, a forward or a new message, could come up as "Compose could not open" instead, and stayed that way until the message was dismissed. The editor inside the window was being thrown away while the window was still appearing. It is now created once the window is on screen. That message also blamed an app update for every failure; it now says so only when part of the app really failed to load.
A message restored from the backup mirror stays in the list and survives Clear cached emails. A copy the backup brought back from the external mirror was named with only the flags the mirror name carried, so MailVault did not count it as archived: once the server deleted the message its row disappeared, and Clear cached emails removed the file, only for the next backup to restore it the same way. Restored copies are now marked archived, every vault copy a backup counts as backed up is marked on that run (including a message MailVault cached when you opened it), and the Microsoft 365 backup names its own copies the same way.
Opening a message never runs anything it carries. A received message's HTML was shown in a frame that was allowed to run script, in MailVault's own window, so a message built to misbehave could act the moment you opened it, with no click needed. Every reading view (the message pane, the conversation and chat layouts, the full-screen view and the Open in window popup) now pins a policy that lets only MailVault's own display code run inside the frame and blocks everything the message itself brings, while dark mode, quote folding and signature folding keep working.
Show original message in a reply can no longer run anything the message carries. The quoted message was drawn straight into MailVault's own window, so markup built to misbehave could run there once you opened it. It now shows in a frame where nothing runs. A plain-text original, and the sender, subject and recipients in the quote header, are quoted as the text they are, so a line like "Ann wrote:" keeps its address instead of losing it.
Blank lines and line breaks arrive the way you typed them. A message written with empty lines between its paragraphs reached the recipient as one block of text: the empty lines had no height anywhere outside the compose window, and the plain-text copy that travels with every message put a blank line after each paragraph and three for every empty line. Both now match the compose window line for line, including a line break made with Shift-Return, and the plain-text copy marks list items, quotes and link addresses. Templates, plain-text signatures and forwarded messages also stop showing their empty lines twice as tall while you write.
Stored mail carries the .eml extension again. Vault files were meant to end in .eml from 2.5.0 onwards, so that a message double-clicks open in Mail and a copied folder is usable anywhere, but only the files that already existed back then were renamed. Everything archived since landed without it. New messages are now written as 1234:2,AS.eml, the same name the external backup copy already used, and the files that missed out are renamed once when MailVault next starts.
Back up now runs now. Clicking Back up now on an account, or Back up all accounts now, starts the backup straight away and ahead of anything the schedule had lined up, even for an account that was already waiting its turn; before, the click was swallowed and the button spun for hours without a backup ever starting. A running backup no longer stops because you came back to the app either. It only pauses when the Mac sleeps or you go offline, and it resumes on its own afterwards. Every account card now shows where it stands, Queued while it waits and a progress bar from the moment its backup starts, whether you started it or the schedule did.
A paused backup picks up where it stopped. When MailVault paused an automatic backup because you went offline or the Mac slept, the queue never restarted: the card kept saying Cancelled with a spinner, the other accounts stayed queued, and Back up all accounts now stayed greyed out. The queue now resumes on its own, the card reflects the real state, a run that makes no progress for fifteen minutes is stopped and retried, and a folder the pause cut short is finished on the next run instead of being skipped.
Outlook folders are stored under one name whatever language you or your mailbox use. With MailVault in German, Spanish or any language other than English, an Outlook account's Sent, Drafts, Trash, Junk and Archive folders were saved under the translated word while the backup saved them under the English one: two copies of each folder on disk, two sets of numbering, and a backup status that could not agree with the folder list. Switching language moved the app to a third, empty copy. The folders are now filed by the name Outlook itself knows them by, so a mailbox set to German ("Gesendete Elemente") files the same way as an English one, the sidebar shows them in your language, and folders already saved under a translated name are moved under the shared one at the next start when nothing else lives there. Nothing is deleted: a folder that already exists under both names stays as it is.
An Outlook backup saves each new message instead of a second copy of an old one. The backup numbered Outlook mail by its place in the folder, newest first, while MailVault gives every message a number of its own that never changes. Each new arrival moved every place along by one, so the backup took the new message for one it already had and skipped it, then downloaded the oldest message again under the new message's number. The backup now files every message under MailVault's number, recognises the copies an earlier backup already saved so they are not downloaded again, and never files a new message over a copy that is already there. A folder whose numbers cannot be read is left untouched and named in the backup's error message instead of being filed by guesswork. Clear cached emails now keeps those numbers too, so mail listed after a clear cannot take a number that is already in use. Copies an earlier backup already filed under the wrong number are left as they are.
v2.13.1September 10, 2026
Added
A move reports its progress. Moving messages from the selection bar, a row menu or the M shortcut now shows the same bottom-right progress card an archive uses: "Moving..." with the count, then "Moved 3 messages to Done" once the server has them. A failed move clears the card, and the folder list says what went wrong, as before.
Fixed
Move works again from the selection bar. With rows ticked, the bar's Move button opened its folder list inside the bar's own scrolling strip, which clipped the list away: it was there, and nothing showed. The list now opens above the bar, beside the delete confirmation, in line with the button.
The collapsed sidebar rail scrolls cleanly. Its account and folder columns no longer grow a second scrollbar over the avatars, All mail, Server and Vault line up with the folder rows beneath them, and in a very short window the rail itself scrolls so the buttons at the bottom stay reachable.
v2.13.0September 10, 2026
Changed
Accounts can be reordered directly in Your Accounts. Drag an account by its grip to change the order in the sidebar and account menus. The separate Account order controls have been removed; keyboard users can move accounts with the arrow keys while a grip is focused.
Added
Incoming mail can play a Mac sound. Settings โ Mail preferences โ Notifications offers Glass, Ping, Pop, Purr, and Tink, with a preview button and an Off option. Sound is off by default and waits with notifications during a Focus session.
Insights shows who you hear from and when. A new sidebar workspace combines a sender map, a timeline by sender, and a daily sent/received calendar. Bubble size reflects frequency and distance reflects recency. Shared filters and message drill-down use available cached and vaulted headers across folders; incomplete coverage and fallback dates are disclosed. Your ordinary mail view stays in place when you return.
Explorer gives your mailbox another way to browse. Switch between List and Explorer, then browse by Date, Sender, or Date โ Conversation. Groups show email, unread and vault counts, support selection and local search, and remember where you left off. Optional day groups add detail; opening a message uses the existing reader and actions. These are automatic views of your mail, with explicit loading for larger mailboxes.
Settings can minimize beside your drafts. Use the minimize button to return to mail, then restore Settings from its bubble or the usual Settings button. Your page, section, scroll position and unfinished edits stay where you left them.
The message list can mark what you are reading instead of what the pointer touches. Settings โ Appearance โ Highlighting offers two ways for the list to show where you are. Follow the pointer is the default and is what MailVault has always done: a row lights up under the mouse, and the message you opened carries a tinted band. Mark what I'm reading turns it around, the way Apple Mail does: the pointer changes nothing, the open message is filled with a solid grey, and the other messages of the same conversation take a lighter grey, so one look tells you what you are reading and what it belongs to. Both work in every folder and every list layout, and the greys are tuned separately for the light and dark themes.
Deleting the message you are reading can open the next one. Settings โ Mail preferences โ Behavior โ After Deleting chooses what the reading pane does once the open message is deleted: nothing, which is what MailVault has always done and is still the default, or open the next message in the list. Delete the last message in a folder and the one above it opens instead. The selection bar's delete follows the same choice, and the setup screen on first run asks for it too.
Fixed
Stars stay visible beside other message indicators. Rows with tracker, warning, or attachment icons keep their star visible; rows without those indicators still reveal an unmarked star on hover.
Explorer navigation keeps focus where it belongs. The main folder no longer shows an unusable Back button, and opening groups with the mouse no longer adds a keyboard focus outline to Back.
Insights has one clear selection. Its sidebar entry aligns with the account rows and is highlighted on its own. Insights uses one account at a time, and sender bubbles reveal their details immediately beside the pointer.
The Sent folder catches up after a message goes out, even on a fast server. MailVault files its own copy of a sent message on the server and waits to hear that it landed before re-reading the Sent list. When the server answered that quickly, and one running on the same machine does (Proton Mail Bridge, for instance), the news arrived before MailVault was listening for it: the Sent list then kept MailVault's provisional copy of the message next to the server's, showing it twice, and the working copy in the vault was never tidied away.
A newsletter that ships its own dark mode is readable again. Some senders swap only their backgrounds when your Mac is set to dark and leave the writing black, and MailVault let that swap happen inside the message view: the mail painted itself black under its own black text, whether the message was drawn light or dark. Messages are now always drawn from the sender's ordinary design, and MailVault does the dark rendering itself, the way it was meant to.
v2.12.0September 7, 2026
Added
A focus session covers MailVault until the timer runs out. A timer in the sidebar footer runs for 15, 25, 45 or 60 minutes, or any number of minutes up to eight hours. While it runs, the window shows nothing but the time left; mail keeps syncing into the vault underneath, and every notification MailVault would have shown waits until the session ends, when a notification says the time is done and the held ones follow. Quitting the app does not end a session: reopening it brings the countdown back with the time that was left. A small "Unlock early" link is always there. It asks whether you are sure, and if you are, MailVault lets you out with a word about the next one. Focus sessions are a Premium feature.
Messages can be starred, and the star follows you to every other client on the account. Hover a row for the star, or use the one in the reading pane, the row menu, or the s key. A starred message is starred in webmail and on your phone too, because MailVault now writes the flag to the server the way it always wrote "read". Replying marks the original as answered on the server, and forwarding marks it forwarded, so other clients show the little arrows.
Folders can be created, renamed and deleted from the sidebar. Right-click a folder for New subfolder, Rename and Move to Trash; the "+" next to Folders makes a top-level one. Deleting a folder files it under Trash, the way Thunderbird does, and only a folder already inside Trash is deleted for good, after a confirmation. Your vault copies follow a renamed folder to its new name; nothing local is ever deleted. INBOX and the special folders (Sent, Drafts, Trash, Junk, Archive) cannot be renamed or deleted.
New mail arrives as it lands, not on the next timer tick. MailVault now keeps one connection per account listening on the inbox (IMAP IDLE), so a new message shows up and notifies within a second or two. The five-minute refresh stays as the fallback for servers without IDLE and for the other folders.
Undo for moves, Trash deletes, stars and read marks. Every one of those actions offers Undo in a small toast for eight seconds, and โZ brings back the last one at any time until the next action replaces it. A permanent delete says so and offers nothing.
Backups can run at hours you choose. Settings โ Backup & Restore โ Backup Schedule has a fourth frequency, "At set hours": pick any hours of the day and MailVault backs up on the hour at each one, only while the app is idle, and never in between. Meant for a vault or backup mirror on an external drive that something else, such as Time Machine, reads on its own schedule: choose the hours that drive is free. A selected hour that passes while the app is busy is skipped, not caught up later.
Changes made offline are kept and sent when the connection returns. Marking read, starring, moving and deleting while offline apply on screen immediately and are queued; MailVault sends them when the network is back (or on the next launch), the same way it already finished deletes interrupted by a quit.
An exported HTML thread follows your system's light or dark appearance. The file used to be white whatever your Mac was set to. Opened on a Mac in dark mode it now draws dark: the rail, the cards and every message, with the pictures inside left as they are. The image export is unchanged and stays light.
Attachments open in MailVault instead of only downloading. A picture or a PDF on a message now has a preview button beside the download one, and clicking the row itself previews it where it can: images inline, PDFs in a reader panel. What you download is kept, so opening the same attachment again is instant and works with no connection; the new "Download attachments automatically" setting fetches a folder's attachments in the background after its messages arrive, newest first. Attachments in All Inboxes used to fail with "Failed to download" because the row could not say which account and folder the message came from; it names both now.
Export can carry a message's attachments. The export dialog has an "Include attachments" checkbox, on by default and remembered. An image export writes them beside the picture, named " - "; an HTML export puts them in the page itself as download links. Only real attachments travel: the pictures already drawn in the body, and tracking pixels, are left out.
Replying starts from the message itself. Clicking a message's header โ in the single reader and on every message in a thread โ opens a reply. The chevron beside it is now a button of its own and is the only thing that folds the details away, so the two no longer fight over the same click. The row's โฏ menu gained Reply, which loads the message first so the quote is the whole message and a thread row answers its newest message, and "New message to ", a blank message to that address from the account the row belongs to.
A conversation can be read three ways. The thread reader has a Layout control: Timeline, the tall column it has always been; Compact, which tightens every message to fit more on screen; and Split view, the list of messages on one side and the one you picked on the other. The choice is remembered, and jumping to the newest message now lands on it in all three.
Closed folders show how much is unread. MailVault asks the server for each folder's unread count when an account comes online and after every Refresh, so the number is beside the folder name in the sidebar โ a badge on the icon in compact mode โ without opening it first.
The list knows a message's size and whether it has attachments before you open it. The paperclip and the size used to appear only once a message had been read, so searching for messages with attachments missed everything in the list that had not been opened. Both arrive with the rest of the row now.
Changed
The Mac installer window was redrawn. The window that opens from the .dmg โ the app icon, the arrow and the Applications folder you drag it onto โ now uses a background generated at the app's own colours and at the size a Retina screen expects, instead of the stretched placeholder it shipped with.
Fixed
A message with no HTML part exports with its text. A contact-form notification or a plain-text reply came out of Export as a header card over an empty body; the text is now in the file, the way the reading pane shows it.
Exporting a conversation from the row menu includes your replies. The menu handed over only the messages in the folder on screen, so a thread of four that held two replies of yours exported as two. The whole conversation goes now, replies from Sent included.
Unfolding a conversation shows your replies too. In the expandable thread view, the rows under a conversation were the folder's own messages only; the replies you sent are now listed with them, in order, and open in Sent when clicked. The thread row's checkbox and menu still act on the folder's own messages.
A reply of yours is no longer drawn as someone else's message. When a reply in Sent happened to share its number with a message in the inbox of the same conversation, the list showed that inbox message twice and your reply not at all.
A message that was read or flagged now goes back to the server. Restoring a message from the vault, or moving one between accounts, sent its flags in a form some servers refuse โ so an unread, unflagged message went through and everything else was turned away. Every message uploads now, and it arrives carrying the date it was written rather than the day it was put back. Run a restore twice and the second run skips what is already there.
A message MailVault cannot place is refused, not fetched from the wrong account. In All Inboxes, opening a row whose account could not be determined used to guess the active account and could show a stranger's message under that number; it now says so and shows nothing.
A damaged header page fails and is retried instead of showing a short list. When a server sends a header MailVault cannot parse, the page used to come back silently shorter; it is now reported and fetched again on the next pass, and the background backfill no longer gives up on the whole folder over one bad line.
A backup to a slow drive can no longer freeze silently. With the vault on an external drive that Time Machine was reading every hour, a large Gmail backup stopped after an hour or two with no message, and Cancel did nothing; restarting stopped at the same place. Each slow write held up a worker until the mail server dropped the connection, and MailVault then waited on that dead connection for ever. Every server wait in a backup is now bounded (a minute per message), so a dropped connection ends the run with the error in the backup card instead of a hang, and the disk work has moved off the threads that keep the connections alive, so a slow drive slows the backup rather than killing it. Messages are also written to a temporary name and renamed into place, so a backup interrupted mid-write leaves no half file for the next run to skip over. And a backup now notices when the drive itself is struggling: three writes in a row that each take over two seconds make it wait half a minute before the next download and say so in the backup card ("Backup drive is slow"), rather than piling more work onto a drive that is already behind; the first normal write clears the wait. The same drive scans that feed the backup status pane and Microsoft 365 backups moved off the connection threads too.
Moving a message no longer clears an unrelated selection. Moving one row from its menu used to deselect everything you had ticked elsewhere in the list; it now clears only what it moved.
Quotation marks in a subject or a name are no longer shown with backslashes. A subject like Pratฤskite ลพurnalo "Iliustruotoji istorija" prenumeratฤ arrived with the server's own escaping still in it, and the list drew the backslashes; so did the To: line in a thread. Messages already in the list keep them until they are fetched again.
Grouping by sender no longer stacks rows on top of each other. Several conversations from one sender that happen to share a subject โ five identical contact-form notifications, say โ were treated as one row and drew over each other, and a conversation from elsewhere appeared at the wrong place in the list. Each conversation is now its own row.
The message you are reading is visible in the list. Selection was a thin line down the left edge, easy to lose next to an unread message's own background; the open message now has a filled background as well.
A message no longer scrolls inside its own pane. Every HTML mail sat in a frame slightly shorter than the mail itself, so the reading pane had a second scrollbar inside it, and anything that arrived late โ a picture finishing, a remote image, a web font โ left the frame short for good. The frame is measured from the page's real box now and re-measured whenever the mail changes height, so there is one scrollbar again.
A large export no longer fails. Exporting a thread that carried its pictures with it produced "Maximum call stack size exceeded" on exactly the conversations with the most in them. Those files run to hundreds of kilobytes and were encoded in a single call; they are encoded in pieces now, whatever their size.
An export cannot hang on a picture that never loads. A message pointing at a remote image on a server that has gone away kept the export waiting; it now waits a bounded moment and writes the file.
Subjects line up down the list. The warning icons โ sender, link, tracker โ were drawn before the subject, so each row began its subject at a different place depending on which warnings that message had. They now sit after it, and the subject starts in the same column on every row, in every row height.
Grouping by sender says where you are. With the list collapsed into senders and topics, the open message could sit two levels down with nothing marking the sender or the topic that held it, and a run of topic rows read as one block of text with no line between them. Topic rows take the same separator every other row has, and the sender and topic holding the open message are marked the way the list marks a selected row.
Clicking your own reply highlights it. In a folder that shows your replies alongside the messages they answer, clicking one of your own selected it but left nothing marked, because the click and the list disagreed about how to name a message that lives in Sent.
Refresh re-reads the folder list. The sidebar's folder list is cached for ten minutes, and Refresh did not clear it, so a folder made in webmail could take that long to appear. Refresh now fetches the list from the server.
The website's language picker goes to the page you were reading. Choosing a language from a guide, a comparison or an FAQ answer sent you to that language's front page instead of that page's translation, and the choice was forgotten on the next page. Every link now points at its own page's translation, and the language you pick is remembered.
v2.11.3September 4, 2026
Added
Conversations can unfold in the list now, or come apart altogether. Settings โ Appearance โ Conversations offers three ways to show replies. Grouped collapses a conversation into the single row MailVault has always shown. Expandable keeps that row and adds a "Show replies" control that unfolds every message in the conversation underneath it, indented, without leaving the list or opening anything. Off gives every message its own row, the way a mail client did before conversations existed. A button in the message list header steps through the three, and its icon says which one you are in; it stays out of the way when you are grouping by sender, where conversations play no part. The first-run tour asks the same question.
MailVault can make itself the default email app on your Mac. The Default email app row under Settings โ Mail preferences โ Behavior used to send you to Mail โ Settings โ General to do it yourself. It now has a button that does it, and re-checks itself when you come back to the window, since macOS may take the window away to ask you to confirm the switch. This works in the copy downloaded from the site; the Mac App Store build still shows the instructions, because the sandbox that build runs inside refuses to make the change.
Fixed
A picture inside a message is still there the second time you open the conversation. An image embedded in the message itself โ a signature logo, a screenshot pasted inline โ drew properly the first time you opened the thread and then showed as its filename in a grey box on every open after that. The copy MailVault keeps in memory so a message reopens instantly was dropping the image's contents on the way in, and the conversation view paints that copy as it finds it. The contents now stay for the images a message actually displays; real attachments are still fetched only when you ask for them.
An account comes back to the folder you left it on. Open a folder, switch to another account, come back, and MailVault could return you to the folder you had been in before that โ Archive, after you had already moved to the Inbox. The folder was written down only at the end of a full fetch, so a click MailVault answered from what it had already loaded, or a click you overtook with the next one, never recorded itself. The folder is now recorded the moment you click it.
Clicking INBOX lists your inbox, not your whole account. On a server that files every folder inside the inbox โ Dovecot's INBOX.Sent, INBOX.Kunden and the rest โ opening INBOX matched all of them and listed the entire account: 26,000 messages where 25 belonged, mail you had moved or deleted still apparently sitting in the inbox, and the inbox's own stored list being overwritten with that mixture every time you moved a message. INBOX is never treated as a branch now, whatever a server calls its folders. Folders that do have folders inside them still list everything filed beneath them, refreshing keeps you in the branch you opened rather than collapsing it to its top folder, "Include subfolders" is offered only where there are subfolders, and the stored lists already spoiled by this repair themselves as they are read.
v2.11.2September 3, 2026
Fixed
A screenshot dropped on the compose window now attaches every time, not every second time. Dragging the floating thumbnail macOS shows after a screenshot onto "Drop here to attach as a file" took the first screenshot, lost the second, took the third, lost the fourth, with nothing on screen to say a file had gone. The thumbnail is not a file yet when the drag starts โ macOS hands the app a promise of one โ and the web engine's handling of that promise produced no drop at all every second time, while the system reported each of those drops as completed. MailVault no longer routes file drops through the web engine: the app takes the drop itself, reads the dropped files, and places them as before โ an image dropped on the message goes inline where the pointer was, anything dropped on the strip or elsewhere in the window attaches โ and a file that cannot be read says why under the toolbar instead of vanishing. One thing changes with it: text dragged from another application into the message, and text rearranged by dragging inside it, is no longer taken on macOS; pasting is unaffected.
Move to folder works again for a message found by search. Moving a message that search had found in another folder โ an INBOX message while another folder was on screen โ failed with "invalid args uids โฆ expected u32". The folder list was handed the message's selection key instead of its number, and the server command wanted the number. Every message now moves out of the folder it actually lives in, whether it came from a search, a branch listing or a merged Sent copy, and a moved message leaves the search results instead of lingering there.
Menus and popovers no longer run off the bottom of the window. The row menu opened on a row near the bottom edge, and the Move to folder list it opens beside it, could end below the window, and the only way to reach the last items was to scroll the list up and try again. Every floating panel now measures itself and shifts to stay inside the window โ row menus, the folder list, the sender and authentication popovers, the copy menu inside a message โ and a dialog taller than the window scrolls instead of being cut off.
Open Folder under Backup Scope & Storage opens the folder. The backup folder lives outside the app's sandbox, and the app only held permission to it while validating or backing up, so a click landing in between was refused by macOS and nothing happened โ not even an error. The button now takes that permission for the click and reports a refusal instead of swallowing it. The backup settings also name the vault's real folder once the vault has been moved.
A dropped connection during sync no longer empties a folder's cached list. When a pooled connection died, the first sync tick failed with "SELECT INBOX failed: io: Broken pipe" โ and when the server closed the socket cleanly, the reply read as an empty mailbox and the sync pruned every cached header to match, logged as "Sync complete: 0 total"; one such prune removed 1,399 INBOX headers. A reply with nothing in it is now treated as a lost connection, and sync and backfill retry once on a fresh connection.
The offline banner stays up while the Mac has no network. With Wi-Fi off and the app idle, the banner appeared and then cleared within 30 seconds, because the sync service's heartbeat reported "online" without ever having tried. The system's own link state now outranks that untested answer.
v2.11.1September 3, 2026
Added
Folders are shown the way your server files them. A nested archive โ Clients, a folder under it for each company, a Done under each of those โ was listed in the sidebar as one flat alphabetical list, so a reader with ten folders called Done saw ten identical rows and nothing to tell them apart. The hierarchy was never missing from what the server sends; it was simply not drawn. The sidebar now shows folders as a tree: a folder with folders inside it carries a chevron, opening it shows what is filed beneath, and MailVault remembers which folders you left open, for each account separately. Reading a message that sits five levels down โ a search hit, say โ opens the folders above it on its own. The Move to folder list shows the same tree, where every folder was previously drawn at the top level under its own name alone; while you are typing a filter there the parents are filtered away, so each row names its parent instead. The Tag Cloud sidebar style nests too: a chip carries its own name and, when something is filed inside it, the same chevron; open it and its children hang beneath it while the chips after it carry on in a new row. Two rules keep the top of the tree useful: a server that files every folder under the Inbox no longer prints that prefix on each one, and the special folders a provider keeps inside a container โ Gmail's [Gmail] โ are listed at the top beside the Inbox rather than a level down.
Open a folder that has folders inside it and you see everything filed under it, and a search can be told to look there and nowhere else. Clicking a parent folder showed only the messages in that folder itself, which for a folder that exists to hold other folders is usually nothing. It now lists the whole branch โ every message in that folder and in every folder beneath it โ newest first, with the total the server reports for the branch, and the list fills in folder by folder rather than all at once at the end, because a twenty-folder branch takes long enough that a list arriving only at the end reads as a folder that found nothing. A folder that will not open costs you that folder alone; its siblings still list. The same message number in two folders stays two rows. The search's folder filter, which offered one folder or every folder on the server, gained an "Include subfolders" box: tick it and the search covers the chosen folder and its whole branch, on the server and in your vault, and the results header says so. "All folders" still keeps a saved message from a folder the server no longer lists, because that mail is still readable.
When the internet goes away, MailVault says so and stops trying to sync until it is back. A machine with no Wi-Fi reported "The server refused the sync", with an icon and a remedy pointing at your server settings, for every account, on every sync โ the connection check only ran when the sync daemon was not there to ask, which is rarely โ while the daemon itself kept dialling every account on every tick and waiting out a fifteen-second timeout for each. Now a banner at the top of the window says "No internet connection", that your mail is still here and MailVault is showing what is already saved on this computer, and offers "Check again"; it clears itself the moment connectivity returns, with no click. While it is up, background syncing pauses rather than failing for every account, tick after tick. An error from a mail server only ever raises a suspicion: MailVault checks the internet itself before deciding you are offline, so one provider having a bad day does not make the whole app declare the network gone. Anything you ask for yourself โ opening a message, deleting one โ is never held back by the banner, because a mistaken verdict must not lock you out of an action you asked for. The old check also froze the window for up to four and a half seconds while it dialled three hosts one after another; the new one dials them together, off the main thread, and answers within a second and a half.
Mail links in other apps can open in MailVault. Click an email address on a web page or in a document and the system hands it to whichever app is the default for mail; MailVault can now be that app. The link opens a compose window with the recipient, subject and body it carried already filled in โ including when the click is what launches MailVault, where the link arrives before there is a window to show it in and would otherwise be lost. The first-run tour asks about it, and Settings gained a "Default email app" row that says whether MailVault opens mail links on this computer and, on Linux, offers to make it so. macOS only lets you choose this yourself, so there the row says where the switch lives โ Mail's own Settings โ General โ rather than claiming a success the system refused.
A single message can be deleted from an open conversation, and collapsed messages say who they were sent to. Finding one reply in a thread that should go used to mean leaving the reader and hunting for its row in the list, because the reader itself had no Delete for a message inside a conversation. Each expanded message now has one, behind the same confirmation the list uses; the message leaves the conversation and the reader stays open on the rest. Deleting a reply from the list while its conversation was open used to leave it in the reader as a ghost, and deleting the newest message closed the whole conversation โ the reader now keeps up, and if the server refuses the delete, the message comes back. A message that exists only in your vault keeps its Delete in the row menu, as before. Collapsed messages in a conversation also now carry a "To:" line, so you can see who each one went to without expanding it.
An open message can be closed. Opening a message was a one-way door: every other way out either opened something else โ another row, another folder โ or destroyed the message. In the stacked two-column layout that is the whole screen, because the list gives up more than half its height the moment a message opens, with no way to get it back. There is now a Close button in the reader's header, on a single message and on a conversation alike, and the list gets its space back.
Settings can open the folder your mail is stored in. "Where your mail is stored" and "Second copy โ external cold storage", both under Settings โ Backup & Restore, each gained an Open Folder button: the first shows the vault in the Finder, the second opens whatever the field above it names โ the external copy when one is configured, otherwise the app's own mail folder. A refusal prints under the row rather than leaving a dead button. The Mac App Store build used to leave the storage section out entirely, because that build cannot move the vault; it now shows the path and the button, and its users are the ones with the fewest other ways to find the folder, since a sandboxed app's files sit under ~/Library/Containers, which the Finder hides and Spotlight skips.
The first-run tour can set the look GraphicMeat recommends in one click. The "Make it yours" step asks five questions โ theme, layout, sidebar style, view and row density โ before anyone has seen a message, and the answers only mean something once you have. A "GraphicMeat recommended" button sets all five to the combination the app is designed around โ dark, three columns, tag cloud, list view, compact rows โ the preview beside them changes as it does, and every one can still be changed afterwards, there or in Settings.
"Report a bug" now leads with the FAQ. The dialog offered four ways to file something and no way to just get the answer. Its rows now read in the order most people need them: the FAQ, in the language the app is set to, then the existing public discussions, then a new report, then email as the private fallback, with the feature request last, since it is not a bug.
The website's docs and FAQ pages search the text of every page, and the FAQ names where your mail actually is. The search box on each hub matched only the words in a question's title, so anything said in an answer was invisible to it. Both now search every guide, comparison, post and answer, and link straight to the section that matched; with scripting off, every page is still one link away. The docs index leads with the pages people arrive for โ FAQ, features, changelog โ groups the guides by topic, and its mobile menu works again. The FAQ's answer about where mail is stored gave the path a development build uses; the shipped app is sandboxed, so its data lives under ~/Library/Containers, which the Finder hides and Spotlight does not search. The answer now names that path and the two Linux ones, says why searching the drive finds nothing, and gives four ways to open the folder. A new answer says how often the folder list is re-read from the server.
Fixed
A message's read state is now one fact, wherever MailVault keeps it. Marking a message read or unread changed it on the server and on screen, but the copy in your vault kept whatever state it was stored with โ and it was always stored as read, whether you had read it or not. That showed up in three places: a vault message rebuilt from its file could paint as unread when it was not, switching away from a folder and back could briefly bring the old state back until the next sync corrected it, and restoring a vault to a new server uploaded every message as read. A change made on another device never reached the vault or the external backup at all. Now the vault copy is stored with the message's real state, a change made in MailVault lands on the vault file, its external backup copy and every cache in one step, and every backup run carries over changes made elsewhere for the messages it already holds.
The Sent folder now syncs on servers that call it something else, and a moment's loss of network no longer costs every account its sync. MailVault asked the server for the folder by the name it had been told โ "Sent" โ and Gmail, which serves it as "[Gmail]/Sent Mail", answered that no such folder exists, so that account's sent mail had never synced at all; a server that calls it "Sent Messages" failed the same way. When the server says a folder is missing, MailVault now looks the name up in the server's own folder list and syncs the folder the server actually serves; when the name was right, nothing changes. Separately, a network blip tore down the connection to every account at once and each lost its whole sync cycle; a connection that fails that way is now retried once. A rejected password is the server's answer and is never retried.
Deleting a message from the reading pane no longer puts it straight back, and a delete the server did not carry out is no longer reported as done. The delete ran on a server connection MailVault had kept open and reused, and a connection the server had quietly closed while it sat idle answered the first command with "connection lost" within milliseconds: the row came back, and the second attempt worked because it happened to get a fresh connection. A delete now notices the dead connection and asks again on a new one โ safe for a delete, because deleting a number the server has already removed does nothing. Writing the check for that found the worse half. MailVault read the server's answer to a delete, and to a flag change, only far enough to see that the command had been sent; a connection that died in the middle of the reply produced no error at all, so the delete was reported done โ the row taken out, the count lowered, and the message stamped "deleted from server", the app's loudest claim about custody โ over a message still sitting on the server. Every delete and flag change now waits for the server's own OK, and the reading pane says why when a delete is refused instead of silently restoring the row.
Deleting a message from the Inbox list no longer deletes a sent message that happened to share its number. The Inbox list shows your sent messages alongside the received ones so a conversation reads whole, and a message's number is only unique inside its own folder. Ticking a received message and choosing Delete from server could delete the sent message under the same number instead: the row left the list, came back at the next sync, and the sent conversation lost a message. The selection now remembers which folder each ticked row came from, so the delete โ and every other bulk action โ reaches the message you ticked. Opening a sent message from the Inbox list also shows that message's own read state, not the received message's.
Marking a sent message unread from the Inbox list now changes that message, not another one. The Inbox list shows the messages you sent alongside the ones you received, so a conversation reads whole. A message's number is only unique inside its own folder, and marking one of those sent copies unread sent the change to the Inbox message that happened to carry the same number: your sent copy kept its read state on the server and on screen, and an unrelated received message could flip instead. The change now follows the message's own folder โ on the server, in the vault and in the list.
Switching folders right after a delete no longer shows the previous folder's messages under the new folder's name. Every delete ends by refreshing the list it ran in, and that refresh takes as long as the server takes. Click another folder of the same account while it is still on its way โ Inbox, then Archive โ and the refresh landed after the switch: the list under the Archive heading was the Inbox, with the Inbox's count, and because MailVault keeps the last list it showed for each folder, the wrong one came back on the next visit to Archive until a fresh sync of that folder replaced it. A refresh now paints only the folder it was started for, and is dropped when the view has moved on to another one.
A folder no longer stays on "server copy not verified yet" after a sync that could not be waited for. The vault glyph on every row says whether the server still holds its copy, and it can only say so once MailVault has listed the folder's messages on the server in full. When a folder opened from a cleared list and the background sync's answer never arrived โ the sync daemon timed out, restarted, or spoke an older version of its protocol โ MailVault fell back to asking the server directly, saw that nothing had changed since its last visit, and stopped there: correct about the folder, silent about the list it was showing, so every row kept the unverified wording until the next successful sync. The direct path now asks the server for the folder's message list the first time it finds nothing changed while that list is still unproven, one request per folder visit and none at all once it is known. The e2e run that caught this was testing against a sync daemon built a month earlier than the app, which is also fixed: the e2e build now stages the daemon it just built as the one the app launches, rather than whatever copy was staged last.
Turning spellcheck off now takes away the red underlines already on the page. The button at the right of the message toolbar has always stopped new mistakes being marked, but every word already underlined kept its mark for as long as the message stayed open โ so pressing it looked like it had done nothing, and the release that introduced the button said the underlines stop. They now go the moment you press it, and come back when you press it again. The underline is drawn by the system rather than by MailVault, and it belongs to the text itself rather than to the box the text sits in, so changing the setting on the box was never going to reach one that had already been drawn. MailVault now re-lays the text when the switch is flipped, which is what actually retracts the marks โ without disturbing what you have written, where the cursor is, or what Undo does next.
A folder shows what is already saved while its sync runs, and a refresh waits for the sync it asked for. Asking the sync daemon to sync a folder and wait for the result could be answered with the result of the previous sync: once an account had synced once, every later wait was satisfied at once by the last answer, and one account's Inbox sync stood in for its Sent sync. Each sync now carries a ticket and a wait is for that sync alone, and a sync the daemon declines still answers rather than leaving the wait to time out. While a sync runs, the folder paints from what is saved on this computer and reloads when the sync lands, so an account with mail already on disk opens on that mail rather than on a spinner. Two smaller things from the same audit: the daemon writes each of its own files in one step, so being killed mid-write no longer leaves a torn file that the next save persists as empty; and a category you set on a message by hand is never overwritten by an automatic one that lands after it.
An exported message names its sender instead of "[object Object]". Every export carried that placeholder wherever the sender belonged โ in the image's filename, in the thread document's summary, contents list and participants line, and in the From, To and Cc rows of the header card drawn into the picture itself. The export read those fields as plain text where the rest of MailVault reads them as a name and an address; it now reads them the way the rest of the app does.
The keyboard steps through All Inboxes again, and its unread filter no longer hides the message you are reading. In the combined list a row is known by its folder as well as its number, and the next and previous keys compared by number alone, so they never matched a row and did nothing. The unread filter compared the same way, so it dropped the open message the moment it was turned on. Both now ask the row where it lives.
"Delete everywhere" is no longer offered on a message MailVault holds no copy of, and the delete that replaces it says where the copies are. The row menu ended with "Delete everywhere" on every row, including a message your vault had never held: there it did exactly what "Delete from server" one line above does, under a name claiming far more, behind a confirmation promising to clear a vault and a backup drive that had never held the message. The last item now appears only where MailVault holds a copy of its own, and it is named for where the message actually is โ "Delete from vault", "Delete from vault & backup", "Delete from server and vault", and so on โ so what the confirmation promises is what happens.
The tour's Premium list shows all ten features without a scrollbar. The list was capped in height and scrolled, so the last two โ "Export as image or HTML" and "Five devices" โ existed only for someone who found a scrollbar nobody looks for on a first run.
A hovered sidebar row no longer touches the selected one. The selected account or folder is marked by a wash of colour rather than a border, and the rows were drawn flush, so a hovered row's shading sat edge to edge against it and the two read as one striped block. There is now a little space between the rows of both lists.
A file dropped on the compose window's "Drop here to attach file" strip is now attached. Dragging a file into a message offers two targets: the message body, which places a picture inline, and a strip beneath it that attaches the file instead. Dropping on the strip did nothing โ no attachment row, no error โ while the same file dropped on the body appeared as expected, so a screenshot could be placed inline but never attached. The strip is only drawn while a drag is over the window, and the window took it down in the first instant of the drop, a hair before the strip's own drop handler ran; with no target left to deliver the drop to, it was discarded. The strip now stays up until the drop has been handled. Dropping elsewhere on the window, and the paperclip button, were never affected.
"Archive All" on a conversation opened from All Inboxes now archives it, instead of failing every message. The combined list stands in for every account at once, so it has no folder of its own; archiving read the folder off the list rather than off the message, and asked each server for a folder by a name no server has. Every message came back an error โ "Archived with 4 error(s)" on a four-message thread โ and nothing was saved. Each message is now archived in its own account and its own folder, which also fixes the same failure from the row's archive button, the row menu, the keyboard shortcut and "Archive selected" whenever the selection spanned more than one folder.
v2.11.0August 31, 2026
Added
The first-run tour now has a back button, and explains every mark MailVault can put on a message. Going back a step was not possible at all: the six screens only moved forward, so a wrong language or a mistyped server meant starting again. There is now one back control, in the same place on every screen, and it respects the shortened tour someone gets when they already have an account. The screen about link and sender warnings used to name four things in words that appear nowhere else in the app; it now lists the warnings by the exact titles the alerts themselves use โ "Dangerous links detected", "Sender impersonation detected", "Reply-To domain mismatch", "Tracking blocked" โ and Settings โ Security explains each one in full, beside a picture of the warning it opens, in every language MailVault speaks. That screen previously described only the two kinds of link warning, and did it in English no matter which language you had chosen, while saying nothing at all about faked senders, mismatched reply addresses or the tracking marks.
The Premium screens in the tour can be stepped through, and their screenshots open full size. Ten features behind a list you had to aim at is a list most people scroll past; there are now previous and next buttons that wrap around, a position counter, and a click on any screenshot opens it large enough to actually read.
Double-click an account in the sidebar to go straight to its inbox. One click on an account takes you back to whichever folder you were last reading in it, which is what you want most of the time and the wrong thing when what you actually want is new mail. Double-click now goes to that account's Inbox, from anywhere โ another folder, another account, or the All Inboxes list.
Any message or thread can now be saved as a picture or as a single web page. Mail is the one archive most people cannot hand to anyone else: forwarding it changes the headers, a screenshot cuts off at the window edge, and printing to PDF renders whatever the printer stylesheet felt like. MailVault now exports a message, or a whole conversation, as a PNG image of exactly what you were reading โ or as one self-contained HTML file. The HTML folds every message in the thread behind a line giving its date and sender, so a forty-message conversation opens as a list you expand one message at a time, with the whole conversation listed down the left in date order โ click any entry to jump to it โ over a pair of buttons that unfold or fold all of it at once. It fits whatever window it is opened in, down to a phone, so there is never anything to scroll sideways; on a narrow screen the list moves above the conversation rather than squeezing it. There is nothing to fetch and no server to be alive: the single script in the file only sizes each message to the window and works those two buttons, and with scripting turned off the file still opens and every message still folds. Remote images are fetched once, during the export, and written into the file itself, so it still reads years later with the network unplugged โ and every file says underneath which account and folder it came from, each message's identifier, and how many remote images were mirrored in, how many the sender's server would not give up, and how many tracking pixels were dropped rather than fetched. Nothing that can execute survives the export: an exported file is opened outside MailVault, where none of the protections around the reading pane apply, so scripts, frames and handlers are taken out before the bytes are written. A conversation too tall for one image is split into numbered pages rather than shrunk, because a soft picture is a worse record than a second file. Export sits in the open message's toolbar, in the thread header, in any row's menu and in the bar that appears when rows are ticked โ and where a message's body is not loaded yet, MailVault fetches it the same guarded way the reading pane does, so a thread exports whole rather than half. This is a Premium feature; without a subscription the same button shows three samples MailVault renders on the spot with the very same code, which you can open or save to see exactly what you would get.
MailVault now speaks nine languages. The whole app โ every screen, every button, every message it puts on screen, the menu bar and the tray icon's menu, the notifications it sends and the errors it reports when a mail server refuses something โ is available in English, Spanish, French, Italian, German, Brazilian Portuguese, Japanese, Korean and Simplified Chinese. Pick a language in Settings and it changes as you watch: nothing to restart, nothing to reinstall. Dates, times and numbers follow the language you chose rather than the one your computer happens to be set to, which matters if you read English mail on a German Mac, or the other way round. The website is translated too โ every page, in all nine, with screenshots taken in each language rather than English pictures under translated text, so what the page shows is what you will see. Nothing about this reaches the network: the translations ship inside the app, and choosing one tells nobody anything.
On Linux, MailVault now says why spelling is not being checked, and what to install. Linux has no spell checker of its own: the dictionary comes from your distribution, and a minimal desktop install often has none โ which looks exactly like a button that does not work. MailVault now checks what is there. Where a dictionary is installed the red underlines appear and the toolbar button turns them off and on as usual; where none is, the button opens the instructions instead โ the one-line install command for Debian, Ubuntu, Fedora, Arch and openSUSE, how to pick a different language, and a link to the guide on the website. When several dictionaries are installed, MailVault checks against the one matching your system language. The snap package now carries English dictionaries of its own, because a confined snap cannot see the ones installed on the rest of the system, and the .deb suggests one at install time.
MailVault now tells you when an email is watching you, and can stop it. Most marketing mail carries a hidden image, usually a single transparent pixel, that your mail program fetches from the sender's server the moment the message opens. That one fetch reports back that you read it, at what minute, how many times you came back to it, roughly where you were, and what you read it on โ none of which you agreed to. Every message MailVault opens is now checked for those beacons, and a small eye appears beside the subject, on the row and above the open message, next to the marks for a faked sender and a mismatched reply address. Click it and MailVault names the company doing the tracking and shows the exact address the pixel would have called. That much is free, for everyone, forever. With a subscription MailVault also takes the beacon out of the message before it is drawn, so nothing is ever requested and the sender is told nothing at all; the eye closes to say so. It works in the reading pane, in threads, in Chat view and in a popped-out message window, and there is a Tracker Blocking screen under Features that shows the same email side by side, tracked and cleared, with the tracking code itself spelled out. Nearly 500 known tracking addresses ship with the app โ merged from the MailTrackerBlocker and Ugly Email projects and extended with senders newer than both โ and the screen links out to both projects, with their licences, so you can read the lists rather than take our word for them. The list is bundled and updated in releases. MailVault never asks a server which pixels to block: doing that would be one more thing reporting on what you read.
MailVault now introduces itself the first time you open it. A new install used to land on an empty mailbox list with an Add Account button and no explanation of what the app was for, which is a poor first impression for something whose whole point is that your mail stops living on someone else's computer. The first launch is now a short tour. It opens on the logo and asks which of the nine languages to use โ asked, not guessed from the machine, because the language your computer is set to is often not the language you read mail in โ and everything after that is already in it. Then it says, in four cards, what MailVault actually does with a mailbox and where the password goes: into the system keychain, not into a file the app writes. Adding a mailbox is one button on that page, and it opens the same account dialog as the sidebar does; there is also "I'll do this later" for anyone without their server details to hand, which carries on through the rest of the tour rather than dumping them at the end. Next it asks how the app should look, with a real message list beside the choice that changes as you pick โ light, dark or following the system, and the density โ so the decision is made by looking rather than by reading the names of the options. The last two pages say what is included for nothing and what a subscription adds, the second with pictures of each feature rather than a list of names, and anything there can be opened later from Settings -> Help without going through the tour again. While all of this is being read, MailVault is already fetching the first mailbox in the background, so finishing the tour lands on mail rather than on a spinner.
Settings -> Billing now says what a subscription buys. It quoted a price against nothing at all: the features it pays for were described on five separate locked panels scattered through the app and on the website, and nowhere in the tab that asks for the money. Billing now lists every Premium feature above the plan card, each with a line saying what it does and, where it has a screen of its own, a link straight to it. The list appears in every build, including the Mac App Store one, because a list of features carries no price. Settings -> Help gained the same gallery, and a link to the FAQ in the language the app is set to.
The FAQ is now six pages instead of one. Twenty-three questions on a single page meant scrolling past everything to reach anything. They are now grouped โ getting started, storage and the vault, mail providers, Premium, backup and restore, and troubleshooting โ behind a hub with a search box that filters the whole list of questions at once. Every answer is plain text that is always visible and needs no scripting to open, every page carries its own structured data so search engines can quote the answers, and old links into the single page still land on the right question.
Fixed
The tour's two-column preview shows where a message is read. Choosing the two-column layout drew a sidebar and a list and nothing else, which said the layout had nowhere to read a message. It has always had one โ the reading pane sits under the list rather than beside it โ and the preview now shows that.
Feature names in the Premium list are no longer cut off. "Scheduled automatic backups", and the longer translations of it, ran past the edge of the button and were clipped mid-word, so the tile named a feature nobody could identify. Names now wrap.
The Continue button no longer moves while you browse Premium features. The panel resized itself to whichever feature was showing, so the button slid up and down under the pointer.
Opening a FAQ topic no longer narrows the page. The FAQ index and the topic pages disagreed about column width, so every click through visibly shrank the text.
The Reply-To warning is translated. Its title was English in all eight other languages, unlike the two warnings either side of it.
A message that refused to open now opens on the first try. Reading mail means asking the server for it, and MailVault keeps a few connections to your mail server open and reuses them rather than starting a new conversation for every message. A connection the server had quietly dropped in the meantime was still handed out, and the message opened onto "Server refused UID FETCH: connection lost". Pressing "Try again" worked โ which made it look random โ because the second attempt happened to get a fresh connection. MailVault now notices that the connection died under it and quietly asks again on a new one, so the first press is the only press.
"Mark as read" works on a message in your vault in the All Inboxes list. Ticking a message the vault holds and choosing "Mark as read" did nothing at all โ no error, no change, the row stayed bold. Messages the vault holds and the mail server does not are kept in a different list inside MailVault from the ones the server just sent, and every read/unread change only ever touched the second one. The change now reaches both, and it is written into the vault's own record of the message, so it is still read after switching folders or restarting rather than quietly coming back unread.
An account switch is no longer overtaken by the one before it. Two switches in quick succession โ which is exactly what a double-click is โ could land on the first one's folder instead of the last one's. The switch that had already been abandoned still painted its own account and folder over the newer one on its way out, and then asked the server to refresh that folder as well. An abandoned switch now stops where it is told to.
Spellcheck marks misspelled words on macOS. The button that turns spellchecking off and on has been in the message toolbar since 2.10.4, and on macOS it never had anything to turn on: the checker built into the system stays off until an app asks for it, and MailVault never asked. Words went unmarked whichever way the button was set โ the setting was real, the underlines were not. MailVault now asks at startup, so misspellings are marked the way they are in every other Mac app, and the button does what it has been saying it does.
Auto-cleanup rules now actually run โ and every existing rule has been switched off until you say otherwise. The rules that archive or delete mail past a certain age were written down by the settings screen in one shape and read by the engine in another: it looked for fields the screen has never saved, worked out an age threshold of nothing, and stopped before touching a single message. Every rule anyone has ever created has been silently doing nothing, run after unattended run. Simply fixing the reader would have been worse than the bug โ rules made months ago, watched to do nothing and forgotten would have woken up on the next launch and started deleting real mail with no warning. So the stored rules have been rewritten into the one shape and every one of them switched off, with a notice on the screen saying why. Turning one back on is a single toggle, and that is yours to decide. A rule the engine cannot make sense of is now skipped and reported rather than treated as though everything were old enough to go.
The rule editor no longer offers a folder the engine refuses to touch. Drafts could be picked, saved and switched on; the rule then sat there looking active and did nothing, because Drafts is protected and always has been. It is no longer in the list, and the two lists โ what may be picked and what may be acted on โ now come from the same place, so they cannot drift apart again.
A new message is sent from the account whose mail you are reading. Compose opened on whichever account sent the last message, so switching account in the sidebar and clicking Compose wrote from the account you had just left โ a difference visible only in the From row, if you thought to look at it before pressing Send. A new message now starts on the account on screen, and in All Inboxes, where every account's mail is in one list, on the account of the last message you opened. An address you have chosen to send as is still remembered, on the account it belongs to. Replies, forwards and saved drafts keep the account they always had.
Changed
Every page on mailvaultapp.com is built from one menu definition. The menu had been copied by hand into each page, so a new page froze it at whatever the page it was copied from happened to have โ twice this left the price out of nearly every page. The release notes page was worse: it is rebuilt on every release from a template that carried its own copy, so publishing a version quietly reverted that page's menu. There is now a single definition every page is generated from, and the links move to the compact menu earlier on narrow screens, where six items in the longer languages had begun to overrun the bar.
An open message no longer carries a second, quieter claim about where it lives. The band across the top of a message says where that message is kept โ in your vault, on the mail server, or the last copy left anywhere โ and a small symbol beside the sender's name said it again, a couple of centimetres below. The two were worked out differently: the band reads the same record as the row you clicked, while the symbol asked only whether the message was in the folder on screen. So a message the band called "Saved in your vault" wore a blue cloud that read "On the server โ not saved to your vault yet". The symbol beside the sender is gone; the band is the message's one statement, and every row in the list keeps its own.
The โReport a bugโ dialog now takes what should exist, not only what is broken. Someone who has just hit something wrong is the same person who knows what the app should have done instead, and that dialog is the only moment MailVault has their attention on the subject. It now offers โSuggest a featureโ as its second row, filing into the Ideas section of the projectโs discussions rather than Bug reports, and its heading says so. Email moved down below โBrowse discussionsโ, because email is the private fallback and a public thread is the one the next person with the same problem can find โ and the dialog now says what an email can cost: MailVaultโs logs carry every address the app has seen, so a log is something you attach deliberately rather than by default. The dialog also carries a link to follow the project, and says who makes MailVault.
A locked feature now says what else Premium covers. Every surface that asks for a subscription carried its own short pitch for the one thing it was gating and nothing about the rest, so seeing the whole list meant going looking for it. They now share a single โSee everything in Premiumโ link out to the feature page, and one locked screen is enough. App Store builds do not show it, for the same reason they do not show the price: that page carries the web subscriptionโs price, and a Mac App Store build must not advertise a purchase made outside it.
v2.10.4August 27, 2026
Added
MailVault can now ask your mail server whether a message still exists anywhere on it. A message you have archived is shown in gold โ "your only copy" โ when the vault on this computer is the last place it survives. That claim used to be worked out from the folder the message was archived from, which is not the same question: archive a message on your phone and it leaves the inbox for All Mail, a rule files it under a label, a delete puts it in the Bin. In every one of those the mail is perfectly safe and the row went gold anyway, so the claim was withdrawn โ and with it the alarm worth having, the one that says someone else deleted your mail and the vault is what is left. Open a message you have archived and the band above it now offers "Check the server". MailVault searches every folder on the account for that exact message, and says what it found: still on the server and which folder has it, or gone from all of them. Only the second answer turns the row gold, and only when every folder actually answered โ a folder that refuses to open is reported as a folder that did not answer, not as an empty one. The verdict is written next to the message on this computer, so it survives closing the app, and MailVault runs the search by itself when a message you have archived disappears from the folder it was archived from.
Spellcheck can be turned off while you write. The toolbar in the message window has a new button at its right-hand end. Press it and the red underlines stop โ in the message and in the subject line โ and press it again and they come back. MailVault remembers which way you left it, so it stays that way for the next message and after a restart, rather than switching itself back on with every new window. The signature editor in Settings is the same editor, so it follows the same switch.
"Report a bug" now offers somewhere public to put it. The button in the sidebar opened a message addressed to one inbox: every report was a private thread between one person and the developer, and the next person to hit the same thing had nothing to search. It now asks where the report should land. "Report on GitHub" opens a new thread in the Bug Reports section of the project's discussions, where it is searchable and where you are told when it is fixed. "Email the developer" is the message as before, with the app version, platform and account details already filled in, for anything you would rather not post. "Browse discussions" opens the list, because the answer may be there already.
Refer a friend. A second button under it opens a new message with nothing filled in but the pitch: what MailVault does, the five things it is for, and a link to the site. Address it to someone and send.
Changed
A "your only copy" message no longer paints its whole row gold. The loudest surface in the app was spent saying something the row already said three other ways: the symbol beside the sender, the label on the open message, and the band above it. The gold wash also had to switch off the highlight that follows the pointer, so the one row you most wanted to click was the one row that did not respond to the cursor. The row now looks like every other row and behaves like one; the symbol, the label and the band still carry the claim.
Fixed
A reply leaves from the mailbox you were reading. Reply, Reply All and Forward opened on whichever account had sent the last message, not the one holding the message being answered โ so an answer to mail in one mailbox went out under another mailbox's address, to a correspondent who had never written to it. A message opened from a mail server carries no record of which mailbox it came from, and that missing record was what the choice fell back on. The account the message is in is now kept with it, and reply and forward leave from that account. Only a brand-new message still opens on the account you last sent from.
The gold "only copy" mark stops going out โ after an archive, and in search results. The mark that says the copy in your vault is the last one left is worked out from a record kept beside each message on this computer, and that record was not travelling with the messages. Two things followed. Saving, archiving or deleting anything in a folder made MailVault rebuild that folder's list from the stored messages alone, so the gold went out on every proven message in the folder โ silently, until something else happened to reload them. And search results were built the same way, so a message MailVault had proved was the last copy left showed gold in its folder and plain grey one search away, which is the wrong way round: search is where you look for a message you are afraid has gone. The record now travels with the messages however the list is built, and a search result carries the same mark as the row it came from, whether you search one folder or all of them.
A backup that saved almost everything no longer reports itself as failed. If a mail server refused to hand over a single message โ one that has been sitting there unread for years, one the server has trouble reading back โ the whole run was reported as a failure, and the notification that arrived said "Backup failed" followed by the words "Unknown error", because nothing was passed along to say what had actually gone wrong. On 27 August that was a run which had saved 788 of 789 messages. A run that saves what the server gives it is now reported as what it is: the account is marked incomplete rather than failed, the notification says "Backup partially complete" and carries the count and the server's own words for the message that did not arrive, and the backup card in Settings shows the same. A run that saves nothing is still a failure, and still retries.
MailVault says when Premium stops applying to this computer. A subscription can end between one check and the next โ it lapses, a payment fails, or the device loses its place to another machine. Until now nothing was said: the Billing tab quietly went back to reading "Free", the features that need Premium stopped, and the only way to find out was to notice something missing. MailVault now says so plainly in Settings โ Billing, explaining which of those happened, and sends a notification so the message arrives even when Settings is not open. Automatic backups are deliberately left running โ billing is never a reason to stop copying mail onto your own disk.
Automatic backups no longer run without a subscription. Asked by someone who wanted to know why backup notifications kept arriving on an install that had never signed in to a paid account. The per-account backup switches were gated; the "Automatic Backup" master switch above them was not โ and that switch is an override that turns on every visible account at once, so a single flip on a free install backed up everything and announced each run, notifications being on by default. The check now sits on the one door every automatic run passes through, whichever of them wakes it. Manual "Back up now" is unchanged and still free. A schedule left behind by a subscription that has lapsed is kept rather than deleted: it stops running, and starts again untouched if you resubscribe.
The dot that means "your backup drive has this" no longer looks like the mark for "saved in your vault". Every row in the list carries a small symbol saying where that message lives: a cloud for one that is only on the mail server, a disk for one saved in your vault, and a different symbol again for the last copy left anywhere. A tiny dot beside that symbol says your external backup drive has a copy too. The dot was painted in the same green MailVault uses for the vault itself, so a message that was only on the server showed a green dot directly above the words "Not saved to your vault yet" โ the colour said one thing and the sentence said the opposite. The dot now carries no colour of its own. Filled means the drive has it, hollow means the drive is not connected and there is no answer either way, and the colour belongs to the symbol it sits on.
An open message now says the same thing as the row you clicked to open it. The band above a message worked out where that message lives without ever asking about the backup drive, while the symbol beside the sender's name a couple of centimetres below it did ask. One could read "On the server" while the other read "On the server and backup drive", about the same message, at the same moment. Both now read the same record, through the same piece of MailVault. The band also names the vault in its first line rather than only in the small print: a message can be on your mail server and on your backup drive and still not be in your vault, and that is the fact worth reading first.
A message in Sent stops borrowing an inbox message's backup. Mail servers number messages within one folder at a time, so number 8 in your inbox and number 8 in Sent are two different messages. MailVault matched copies on the backup drive by that number alone โ and the inbox view shows your replies from Sent inside its conversations, so a reply that had never been backed up could wear the mark of an unrelated inbox message that had. Backup copies are now matched by folder as well as by number, MailVault reads the Sent folder's backups alongside the folder you are looking at, and a message in a folder it has not read is reported as unknown instead of as "not on your backup drive" โ an answer nobody had asked for.
MailVault stops mentioning a backup drive you never set up. The small dot beside each message's symbol has three states: filled when your backup drive holds a copy, hollow when the drive is not connected and there is no answer either way, and absent when there is no copy on it. MailVault could not tell "the drive is unplugged" apart from "there is no drive", so every message belonging to someone who had never chosen a backup location wore the hollow dot, and the message you opened said "Backup drive not connected โ can't verify" โ a complaint about a feature that had never been turned on. With no backup location configured, nothing is drawn and nothing is said. A drive that has been set up and is not reachable still reports itself as exactly that.
The line under the mailbox name says what it is counting. It read "1,213 of 1,630 loaded in your vault", which reads like something still loading, and it sat directly under another count whose "of" meant the whole mailbox on the server โ two lines, two meanings, one word. It now reads "Vault: 1,213 of 1,630 loaded": of the messages MailVault has loaded into the list so far, that many are saved in your vault.
The whole app no longer slides out of its own window. MailVault fills the window exactly โ nothing sits above the sidebar and nothing below the message list โ so there is nothing to scroll. A firm two-finger flick on the trackpad dragged the whole app downwards anyway, leaving a band of empty black where the panes had been and no scrollbar anywhere to pull them back. The window itself now stays put. The message list, the open message and the folder list scroll exactly as before.
v2.10.3August 26, 2026
Fixed
A message in a conversation stops showing its subject where its text should be. MailVault keeps a copy of every message you open on this computer, filed under the number its mail server gave it. Those numbers are only meaningful to one server: move a domain to a new mail host and the new server hands the same numbers to different messages, so the copy filed under a number is somebody else's mail. MailVault noticed that and gave up โ and the conversation then printed the message's own subject line, in italics, exactly where the message should have been. It reads as an email one line long. MailVault now asks the server for the message you actually clicked, and if that fails too it says the message could not be loaded rather than quietly showing you something that looks like the real thing.
"View Source" shows the message you are looking at. The raw source was read straight out of the stored copy filed under that number, with nothing checking it was the right message โ so after a change of mail host it could hand over another message's headers and body under the header of the one on screen. The source is now checked against the message it claims to be, and MailVault says so plainly instead of showing the wrong one.
A backup no longer undoes MailVault's own repair of your archive. When a mail server reissues its message numbers, MailVault repairs the archive on this computer: mail the server still has is refiled under its new number, and mail it does not have is set aside โ kept on disk, never deleted. The next backup then copied those set-aside messages back off the backup drive into the archive, under the numbers they used to have, undoing the repair. Every backup did it again, and nothing showed that it had happened. Messages the repair set aside now stay set aside, while a copy it never ruled out still comes back from the backup drive as before. An archive that was already affected keeps its wrong copies until the next repair runs.
A bulk archive or delete now says what it is doing to a screen reader. Moving thousands of messages off a server reported its progress in a bar and nowhere else, so with a screen reader on, the longest and least reversible operation in MailVault ran in silence. Bulk save, bulk operations and the selection bar now announce the phase, each quarter of the way through, and how it ended โ including how many failed โ without reading out every percent for the length of the run.
A narrow window no longer pushes the message out of sight. Below 768px wide the list and the message stack one above the other, and the height of the list came from the same setting as its width in the three-column layout. Widen the list with the divider, then make the window narrow โ half a screen, or the smallest size MailVault opens at โ and that width became a height taller than the window: the message you clicked was rendered below the bottom edge, along with the divider that would have brought it back, so clicking a message showed nothing and there was no way to undo it from inside the app. The two layouts now keep their own sizes, neither can be dragged past what the window can hold, and the stacked layout gives the whole window to the list until you open something โ instead of holding half of it for a pane that says "Select an email to read".
Settings stops hiding its own tabs in a narrow window. In General and in Backup & Restore, the row of tabs ran off the right-hand edge โ "Notifications" and "Keyboard Shortcuts" were simply not on screen, in a strip that scrolled sideways with nothing to show that it could. The tabs now wrap onto a second line, and the settings list on the left takes less room when the window is small.
A narrow message list keeps more of the subject. The sender column was a fixed width whatever the list was doing, so in a half-screen window it took nearly as much room as the subject beside it. It is now a share of the row: unchanged at the widths it has always had, and it gives way first when the list is narrow, because a subject is what a list is read for.
The layout picker says when three columns will not fit. Choosing "Three Columns" in a window too narrow to hold them did nothing at all, with nothing to explain why. Settings โ Appearance โ Layout now says the panes are stacked until the window is widened, and that the choice is remembered.
"Subject:" fits its label in the compose window. The label was five pixels narrower than the word.
v2.10.2August 25, 2026
Added
A message you are writing is saved to Drafts as you type. Until now a half-written message existed only in the window it was being typed in, so anything that closed that window took the text with it. Three tenths of a second after you stop typing, the message is now written to the Drafts folder of the account it will be sent from, on this computer โ recipients, subject, body and attachments โ and it shows up in that folder like any other message. It is one draft, not one per pause: each save replaces the last. Change the From address to another account and the draft moves to that account's Drafts. Send the message, or discard it, and the draft goes away with it. A message with no recipient yet is saved too โ that is the point. Nothing is uploaded to the mail server yet; this is the local copy only.
A draft in the Drafts folder opens back up for writing. A message saved as you typed could be read back but not continued: clicking its row opened it in the reading pane, like any other message, and the only way to carry on was to start again. Clicking a draft you wrote now reopens it in a message window โ recipients, subject, body and attachments as you left them, sent from the account it belongs to โ and carrying on updates that same draft instead of leaving the half-written one behind. A reply you had started keeps its place in the conversation. Mail archived from a server is unaffected: it still opens in the reading pane.
A link to the other apps from the same maker. Help โ "More Apps by GraphicMeat", and a matching row in Settings โ Help & Support, open graphicmeat.com.
Fixed
A search result opens the message you searched for, not another one on the same number. Search looks across every folder, but a result carried no record of which folder it came from โ so opening one went looking in the folder the sidebar happened to have selected. Two things followed. If that folder held a message with the same internal number, that message opened instead, under the header of the one you clicked. If it did not, the message would not open at all and MailVault reported it as no longer on the server. Results now carry their own folder, and two messages that share a number in different folders stay two separate results.
Selecting text in a message you are writing no longer folds it away โ or loses it. Sweeping a selection past the edge of the compose window counted as clicking away from the window: the message collapsed into a draft bubble. Opening the bubble and doing it again was worse, because a message brought back from a bubble was treated as untouched โ so that second time it closed for good, with no "Discard message?" prompt, and everything typed was gone. A selection that begins inside the window is now only a selection; clicking away still minimizes, but only when the click both starts and ends outside. A message restored from a bubble is unsaved work again: clicking away minimizes it, and Close asks first.
A search across "all folders" now really searches every folder on the server. The results header said all folders, but a search of the server only ever looked in the Inbox โ so a message sitting in any other folder came back as a message that does not exist, which is exactly the check people make when a backup looks smaller than the mailbox it came from. The search now walks every folder the account has, Inbox first, filling the results in as it goes and showing which folder it is on, so a sweep of sixty folders no longer reads as a search that found nothing. A folder that refuses to open is skipped instead of ending the search, retyping the query abandons the old sweep, and the folder picker now lists folders nested inside other folders, which were unselectable before.
Help โ "MailVault Website" opens the site that is actually there. The menu item, and the two update dialogs that name the website, pointed at mailvault.app, which is offline. All three now open mailvaultapp.com. The same link is in Settings โ Help & Support, where Windows and Linux can reach it too.
Folder names with accented letters read the way they are spelled. A folder called "Bokelmรผhle" showed up as "Bokelmu&Awg-hle" โ in the sidebar, above the message list, in the folder pickers, and in the backup coverage list. Mail servers send folder names in an escaped form, and MailVault was printing that form as-is instead of turning it back into letters. Every place a folder is named now shows the real name, whatever alphabet it is written in: รครถรผรฅ, accents, Cyrillic, Japanese. Nothing on disk changed โ a folder in your archive is still stored under the name the server gives it, so a backup made before this update restores exactly as it did.
v2.10.1August 24, 2026
Added
A new message opens from the account you last sent with. With several accounts set up, a new message always opened from whichever account happened to be active, and the address had to be corrected every time. Compose now remembers the account โ and the exact From address, if an alias was picked โ of the last message that went out, and starts the next new message from it. Replies are unaffected: they still go out from the account that received the message, and a draft reopened from its bubble, or brought back by Undo, keeps the identity it was being written with.
Pick the address a message leaves from, right in the From row. Settings โ Accounts still sets the address an account sends from by default, but the From row of a new message now lists every address the account can use โ the login address, the "Send Mail As" address, and any address the account has sent from before โ grouped under the account. One message can go out from a different alias without changing the setting. An account with a single address shows as before.
Drop a picture into the message, or a file onto the strip below it. While you drag a file over a new message, two drop zones light up: let go of an image on the message body and it goes inline right where you dropped it; let go of anything on the dashed strip below the body โ or anywhere else in the window โ and it is attached as a file. Pasting an image from the clipboard puts it inline too. Inline pictures are sent the way other mail apps send them, as embedded parts the message refers to, so Gmail and Outlook.com show them instead of stripping them out.
Time Capsule and Email Cleanup now say what Premium costs, and offer a way to get it. Both panels explained the locked feature and stopped there โ no price, no button โ while the other three locked panels showed both. They now carry the same price line and Upgrade button, which opens Settings โ Billing.
Changed
Fastmail forms call the sign-in field "Login Address". Fastmail signs in with the @fastmail.com address and sends from aliases, so the add-account form and Settings โ Accounts now label that field "Login Address" and point to "Send Mail As" for the address you hand out. Other providers are unchanged.
Fixed
A quoted reply that arrives without a marker is folded away like any other. When someone replies to their own message โ Fastmail does this, and it is common on a phone โ the message being quoted arrives with nothing marking it as a quote, so MailVault showed all of it under the reply and the same conversation ran twice down the page. That quote is now recognised by its "Original Message" header and tucked behind the "โฆ" button, with the From, Date and Subject lines left in view, exactly like the quotes every other mail app sends. Quoted plain-text mail written the same way folds too.
A message you send keeps the spacing the compose window showed. Paragraphs went out with no spacing of their own, so the mail app at the other end โ MailVault's own reading pane included โ filled in its default and a message written with single blank lines arrived looking double-spaced. The spacing now travels with the message, so what you see while writing is what lands.
A message with a very long subject no longer pushes the app off the screen. Opening a conversation whose subject runs on in one unbroken line โ a delivery report, say โ stretched the app wider than its own window: the right-hand side of the message was cut off with no way to reach it, and selecting any text slid the whole window sideways and would not slide back, leaving the message list off-screen so nothing else could be opened. The layout now fits the window whatever the subject, an over-long subject is shortened with an ellipsis as it always should have been, and no part of the app can be scrolled out of reach.
A message deleted somewhere else no longer leaves a dead row behind. Deleting a message from another mail app, a phone, or a webmail tab left its row in MailVault's list โ at the top, if it was the newest โ and every click on it failed. It came back after every restart too, because the local header cache still had it. When the server states the message is not in the folder, the row now goes with it, and the reading pane says why rather than the row just disappearing. Nothing is removed from your archive: a message you had saved locally stays, and simply switches to "Local only". A failed or refused fetch never removes anything โ only the server saying the message is gone does.
A server that will not hand over a message no longer reports it as deleted. When a server refused to send a message's contents, MailVault asked once more whether the message was still there โ using the same question the server had just refused, so the second silence read as "this message is gone" and the reading pane said "Email not found" for mail sitting right there in the list. Clicking it again changed nothing. The check now only accepts an explicit answer from the server, so a refusal, a dropped connection or a stalled one is reported as what it is โ with the server's own wording โ and a message is called missing only when the server says so, naming the message and the folder.
Replying to a message you sent now addresses the people you wrote to, not you. Replying to your own message โ from Sent, or the copy delivered back to you โ put your own address on the To line, so the reply went to yourself and the actual conversation partner never saw it. When the message being answered came from any of your own addresses, including a "Send Mail As" alias, the reply now goes to its recipients instead; Reply All also stops re-adding your own aliases to the To and Cc lines. A note genuinely sent to yourself still replies to you.
A comma in a contact's name no longer breaks sending. Picking an address-book contact named "Doe, John" put that name on the To line unquoted, and everything after the comma was read as a second, broken recipient โ the send failed with an error about an invalid address. Names with commas are now written the way the mail standard requires ("Doe, John" in quotes), and the sending side no longer splits a recipient list inside quotes or inside an address, so stray and trailing commas are ignored rather than fatal.
The "/" key can be typed into a message again. "/" is the shortcut that jumps to search, and it fired even while typing โ in the message body, the subject, or any address line, the character never appeared and the cursor jumped to the search box instead. Shortcuts bound to printable keys now stay out of every place you type; "/" from the message list still jumps to search.
Replying no longer breaks a conversation into new threads. Every reply MailVault sent named only the message it answered and not the conversation behind it, so the other person's mail app carried on from that shortened history: their answer started a thread of its own, and three replies left three rows for one conversation. Replies now carry the whole conversation, and the list groups messages whose history was cut short by any mail app โ so the conversations already split in your mailbox come back together as one.
Outgoing mail now carries a properly formed Message-ID. Every message MailVault sent was missing the angle brackets the mail standard requires around its Message-ID. Some receiving servers and spam filters count a malformed header against a message, and other mail apps key replies to that header, so the conversation could fail to line up on the other end. The header now goes out in the standard form, and the copy filed in Sent still matches it.
"Send Mail As" no longer suggests people you were merely copied alongside. The suggestion chips under the field mined the To and Cc lines of received mail, so a mailbox that is often copied with the same colleagues was offered their addresses as aliases. Being on a thread is no proof that mail to an address lands in this mailbox, so that source is gone: the chips now list only addresses this account has actually sent from, under "You've sent as:".
Premium prices are quoted in the currency you will actually be charged, on every screen. The panels for locked features worked the currency out from your computer's language settings, while the Billing tab โ and the checkout that takes the money โ works it out from where you are. A machine set to British English inside the eurozone was offered "ยฃ3.50/month or ยฃ21/year" on the Migration panel and "โฌ4/mo" on the plan card two clicks later, then billed in euro. Every price in the app now comes from the same place as the charge, and is remembered so it is right the moment a panel opens. The pricing, home, features and FAQ pages on the website do the same, instead of quoting US dollars to everyone.
Dragging a file from Finder onto a new message does something again. The drop never reached the compose window โ the desktop layer accepted the file and kept it โ so nothing was attached and nothing said why. Dropped files now land in the message or its attachments, as above.
Forwarding no longer sends the original message twice. A forward put the original into the body and also kept a second copy behind the "Show original message" toggle, and both went out. The forward now carries the original once, in the body where you can edit it.
Closing an untouched message no longer asks whether to discard your changes. A new message that held only your signature, or a forward you had not typed into, counted as unsaved work: Close asked to discard it and Escape minimized it to a bubble instead of closing. Only what you actually typed, added or attached counts now.
Escape inside the "Discard message?" prompt keeps the draft. Pressing Escape there closed the prompt โ and, in the same keypress, closed the message behind it and threw the draft away. Escape now only dismisses the prompt.
Undo in a new message is no longer lit before you have typed anything.
v2.10.0August 18, 2026
Added
Send from a different address than the one you log in with. Settings โ Accounts now has a "Send Mail As" field: leave it blank to send from your login address, or enter an alias your provider lets the account send from โ useful on Fastmail and anywhere the sign-in address is not the address you hand out. Only the "From" address on outgoing mail changes; your username and password stay exactly as they were, and no Reply-To header is added. MailVault suggests addresses it has seen in your own mail (ones you have sent as before, and ones mail addressed to you arrives on), and a Verify button sends a single test message from the address โ to your own mailbox by default โ so you can confirm your server accepts it before you rely on it. If the server refuses the address, the error now says so plainly instead of reading as a password problem.
An unread-only filter for the message list. The envelope button in the list header hides everything you have already read; press it again to bring it back. Conversations stay in the list while any message in them is unread, the message you currently have open stays put even once it is marked read, and the header says how many unread messages it is counting โ including how much of a large mailbox has been loaded so far, since the filter can only see mail MailVault has already fetched. When nothing is unread the list says so and offers a way back to all messages.
Delete Everywhere โ remove selected emails from the server, this computer, and the external backup in one action. Available in bulk operations, the selection bar, and the row menu.
Bulk operations selection now checkmarks the rows and survives closing the modal โ a bubble shows the account, folder, and live count, and the selection can be amended by hand before starting. The session is bound to one account, folder, and view (list or thread); navigating away ends it.
Row hover menu now offers every action the selection bar does: mark read/unread, archive, unarchive, move, delete from server, delete everywhere.
A bulk run can now report emails held back because the mailbox needs a resync, instead of silently skipping them.
Changed
Bulk operation descriptions now state which of the three storage locations (server, this computer, external backup) each action touches, and "Delete from Server" states per-selection whether local copies survive.
Fixed
The selection bar and Bulk Email Operations no longer disagree about how much is selected. With 65 emails picked, the modal said "65 emails selected" while the bar along the bottom said "52 selected (65 emails)" โ it led with the number of conversations those emails belong to, not the number of emails every button on it acts on. The bar now leads with the message count and names the conversation count for what it is: "65 selected (52 conversations)". The conversation count was also short whenever the selection reached mail further back than the list had loaded, which a date range in bulk operations routinely does; those messages are now counted as well.
Outlook mail saved on this computer is shown newest-first again, and is no longer thrown away. Outlook gives its messages no number of their own, so MailVault assigns one the first time it sees each message โ working through the folder newest first, which means the oldest mail ends up with the highest numbers. Two things went by those numbers as though they ran the other way. Opening an Outlook account showed the saved copies with the highest numbers, so the list filled with the oldest mail in the folder until the server answered. And the check for messages deleted from the server treated everything below the newest page as gone: refreshing a folder MailVault held more of than one page could delete hundreds of saved messages that were still on the server. Both now go by the date on the message, and mail whose date cannot be read is left alone rather than removed.
A conversation's subject is back in the email list. Rows that group several messages together showed the participants, the message count and the date but no subject at all at the standard list width โ the subject was squeezed to nothing rather than shortened, so the row read as mail with no subject. Widening the list brought it back. Conversation rows now keep room for the subject and shorten the participants instead, the same way single-message rows already did.
Premium prices in the app now match what you are actually charged, in your own currency. The panels for locked features quoted "$3/month or $25/year" โ a price that changed months ago โ and quoted it in dollars no matter where you are. They now show the price for your machine's region: pounds in the UK, euros across the eurozone, dollars in the US, and euros elsewhere, which is what checkout bills. Prices ending in a half unit, such as ยฃ3.50, are no longer written as "ยฃ3.5" on the Billing tab.
Mail saved before you changed email providers is no longer mistaken for other messages. Each saved message is filed under the number its server gave it, and those numbers belong to one server: when you move to a different provider โ or a provider renumbers a mailbox on its own โ the number on a saved message points at whatever the new server put there instead. MailVault stopped showing the wrong message when you opened one, but everything else still went by the number: messages were marked as saved to this computer when the saved copy was a different email, "delete everywhere" and bulk actions aimed at it, and the old copies sat in your storage unreachable and uncounted. MailVault now records which server generation a mailbox's saved mail belongs to. When that changes, it matches every saved message to the new server by its Message-ID and files it under its new number, so your saved mail, and the marks that go with it, come back intact. Anything the new server does not have is set aside instead โ never deleted, since your copy may be the only one left โ and Settings โ Storage offers to remove it once you have seen what it is. Messages you wrote here that never reached a server are left alone.
A message no longer shows mail from the account's previous email provider. After moving a mailbox to a different provider, the new server hands out its own message numbers, and a message MailVault had already saved to this computer could be filed under a number the new server had since given to something else. Opening the row showed the old, saved message in full โ its sender, its date, its subject and its body โ with nothing to say anything was wrong. Every saved copy is now checked against the message it is opened for, and a copy that turns out to be a different message is ignored in favour of the server's.
"Delete everywhere" no longer reports success on an Outlook message it did not delete. Outlook messages are addressed by their position in the folder listing, which shifts every time mail arrives or leaves, so MailVault could lose track of which message a row pointed at. When that happened the delete was skipped, the row disappeared anyway, and the message came back on the next reload. MailVault now uses an address carried by the row itself, re-reads the folder when that is not enough, and when it still cannot identify the message it reports the delete as failed and leaves the row โ and every local copy โ where it is. The same fix applies to deleting, moving, and marking Outlook mail as read.
An Outlook message now keeps the same number, so the copy saved to this computer stays attached to the message it came from. Outlook gives its messages no number of their own, so MailVault used each message's position in the folder โ which moves every time mail arrives or is deleted. A single new email could shift every message down by one, and the copy saved to this computer was then filed under a number that already belonged to something else: the same email could be saved twice under two numbers, while a third number pointed at mail it never held. MailVault now gives each Outlook message a number of its own the first time it sees it and keeps it for good, so the saved mail, the email list and the folder stay in agreement. Accounts already set up keep the numbers they have.
A phishing warning no longer follows a number into the wrong mailbox. The red and amber link warnings were filed under a message number that is unique only inside one folder, so a warning raised on one account's message lit up on an unrelated message with the same number in another account or folder โ and hovering it listed the other message's links. Warnings are now tied to the account and folder they were raised in; existing saved warnings are discarded and re-checked as each message is opened.
An open message no longer shows another message's contents. The reading pane could render a completely unrelated email โ from another folder, or another account โ underneath the right sender and subject. A message is identified by a number that is unique only inside one folder, and the link checker filed each message's prepared body under that number alone, so the next message to reuse it was handed the earlier one's body. Every prepared body is now tied to the message it was built from.
A short email list now fills itself in instead of waiting for a second reload. The list could settle at "3 of 11 emails" and stay there: the check that runs on every account switch and reload asks whether the local copy matches the server, and when the answer was "nothing has changed" it returned without noticing that the list on screen was showing far less than the copy it had just verified. Clicking reload landed in that same check and appeared to do nothing; a second click a while later brought everything back. The check now compares what is on screen against what is stored and loads the difference, and the reload button in the "Showing cached data" warning always reaches the server instead of answering from a check made moments earlier.
A dropped connection no longer looks like an account with no folders. If the connection died while the folder list was being read, MailVault treated the silence as an answer โ "this account has no folders" โ and showed the "Showing cached data" warning while quietly holding a broken connection. It is now recognised as the failure it is, so the connection is replaced and the folders come back on the retry.
Deleting emails from the server is no longer lost if the app is closed or reloaded while the delete is still going. The delete is recorded before the rows disappear and finished the next time the app starts, so a message you were shown as deleted stays deleted.
Email subjects no longer vanish from the list when a message's date includes a year โ older mail showed only a sender and a date in a narrow list.
A message deleted while switching accounts could take an unrelated message with it, or fail to stay deleted after a restart.
Deleting archived emails from a folder left the local copies behind, so the rows reappeared as "Local only" and the delete looked like it had done nothing.
The key under the email list is readable again, and its explanations are visible. Its four entries were squeezed until the labels broke mid-phrase, and hovering one opened its explanation below the bottom edge of the window, where it could not be seen at all.
A message whose body fails to arrive now says so. The reading pane printed the subject line where the body belongs, so a message that never loaded looked exactly like a message with one line in it. It now shows a loader while the body is on its way, and if it never comes, a plain "Couldn't load this message" with the reason and a Try again button.
"Email not found" no longer stands in for a server that refused. A server that declined to hand over a message ended the exchange in a way MailVault read as "there is no such message" โ for mail sitting right there in the list. It now checks whether the message is still on the server before reporting it missing.
Opening a message no longer waits behind the ones being fetched ahead of it. MailVault reads the next few messages in the background so they open instantly, and that background reading was using the same limited set of connections as the message you actually clicked. It has its own now, it stops as soon as you move to a different message, and a message read that stalls gives up after 45 seconds instead of spinning forever.
v2.9.2August 8, 2026
Added
Email signatures are now formatted, not plain text. Settings โ Accounts gives the signature the same editor as compose: bold, italic, underline, links, lists and quotes, all carried into the messages you send. Existing plain-text signatures are kept as they are.
Signature and display name save as you type. The "Save Changes" button is gone โ edits are stored automatically, with a brief "Saved" mark next to the section title.
After a successful manual backup, MailVault now offers to automate the next ones. A one-time panel suggests scheduled backups once your first manual backup completes, and a small "Automate" chip stays on the account's backup card afterwards. Shown once per install, never stacked with the star-and-share panel.
Fixed
A message in a conversation no longer shows the contents of a completely different email. Opening a thread could render an unrelated message โ sometimes from another folder or even another account โ under the right sender and subject. A message is identified by a number that is only unique inside one folder, and the thread view worked out which folder to read from by looking at whichever mailbox happened to be on screen; when that guess was off, the same number pointed at a real but unrelated email. Each message now carries its own account and folder, and when its identity can't be confirmed MailVault shows nothing rather than someone else's mail. The same guess is gone from attachment downloads, "View source", and "Delete thread from server", which could previously act on the wrong message.
Signing in to Premium now tells you what it found. Choosing an email address that has no subscription โ or one whose subscription has ended, or whose checkout was never completed โ ran the check, stopped the spinner and changed nothing on screen, which was indistinguishable from the button not working. Sign-in now explains what the billing server holds for that address and what to do next. If the plans themselves can't be loaded, the page no longer shows blank space where they should be: it says so, offers a retry, and can open the plans in your browser. Signing in also re-checks free-trial eligibility for that address, so the trial badge stops promising a free trial to someone who has subscribed before.
The "Showing cached data" warning no longer appears โ or refuses to leave โ when MailVault rebuilds its email list from your saved copies. If the fast email index was missing while the saved mail itself was intact, opening the account raised a warning banner even though this rebuild is routine and heals itself within moments. Worse, once anything raised that banner, the quick "has anything changed on the server?" checks that run on every account switch skipped the code that removes it โ so the warning sat there for the rest of the session, and its reload button appeared to do nothing. The rebuild is now silent, and every check that confirms your mail matches the server also clears the warning, so the one remaining genuine warning (the server unexpectedly claiming a mailbox is empty when you have mail in it) disappears by itself as soon as the server checks out.
"Mark unread" now closes the email and sticks. Marking the open message unread left it on screen, and opening it again brought back the state it had when it was first read โ so the button still offered "Mark unread" for a message the list showed as unread, and the message was never marked read again no matter how often you opened it. Marking unread now closes the message, and reopening it marks it read as usual, so the button always names what happens next. Opening a message also updates its row and the sidebar's unread count straight away instead of waiting for the next refresh.
Buttons that did nothing are gone from the conversation and chat views. Archive, Delete, Move and Mark read/unread appeared under each message in a thread and on chat bubbles but were never connected to anything โ clicking them did nothing at all. They now appear only where they work.
Headings and text in newsletters stay readable in dark mode. Some senders pin a text colour in a way that overrode MailVault's dark conversion, so headings kept their original black and disappeared into the dark background while the rest of the message converted normally. Those colours are now converted like everything else, and brand colours that convert correctly are left as they were.
Conversations show your own replies on a first run too. On a freshly installed or freshly reset account, the Sent folder was looked up a moment before the folder list came back from the server, found nothing, and never looked again โ so INBOX threads were missing every message you had sent, for the rest of the session. Switching accounts and back was the only way to get them. The lookup now waits for the folder list.
Your folders no longer go missing, leaving only INBOX in the sidebar. If the very first folder lookup of a session ran a moment before the account's password was ready, it failed and was never tried again โ the account showed a single INBOX until the app was restarted, and "Move to folder" had nothing to offer. The lookup now retries, and switching accounts no longer paints the old one-folder placeholder back over a list that had already loaded.
Marking a selection as read or unread now updates the list right away. Selecting messages and using the selection bar's read/unread buttons changed the messages but left the rows looking exactly as before โ the unread highlight, the bold subject and the thread's unread count only caught up after switching folders. The sidebar's unread badge now follows too, and the buttons work for Outlook/Microsoft accounts, where they previously did nothing.
Moving a selection to another folder empties the rows immediately instead of leaving them in the list until the next refresh finished.
Formatted emails no longer sit in a lighter grey box in dark mode. HTML messages โ which includes every reply you write โ were shaded slightly lighter than the app behind them, so your own replies looked boxed next to plain-text mail in the same thread.
No more empty space under an email with a folded quote. The message area grew a little on every measurement instead of settling on the content's real height, leaving a gap below the "โฆ" button. Expanding or collapsing a quote in the single-email view now resizes the message too, as it already did in thread view.
Your own reply no longer renders as a copy of the message you replied to. When the quoted message carried a complete HTML document inside it (Proton Mail does this), MailVault displayed only the quote and hid everything you wrote. The email itself was always sent and stored correctly โ this was a display bug in the thread and single-email views.
v2.9.1August 6, 2026
Added
Proton Mail works now โ pick "Proton Mail Bridge" in the provider list. MailVault connects through the locally-running Proton Mail Bridge app (127.0.0.1:1143), including its STARTTLS handshake and self-signed certificate, which are handled automatically for local connections. A setup guide is linked right from the provider screen.
Custom IMAP accounts can choose their connection security. A new Security selector (SSL/TLS, STARTTLS, or None) appears when adding a custom account and when changing an existing account's server โ previously MailVault always assumed SSL/TLS, so servers on STARTTLS ports couldn't connect. The IMAP port follows the chosen mode's default (993 or 143) until you type your own.
The provider list now shows every supported provider, including Zoho, Proton Mail Bridge, and Fastmail, in a two-column layout.
See exactly how much mail data each account transfers. Hover an account in the sidebar for a seven-day chart of what it downloaded and uploaded, with today's, this week's and this month's totals โ click it for the new Settings โ Data Usage page and its daily, weekly, monthly and yearly breakdowns. Useful for keeping an eye on provider limits โ Gmail suspends IMAP access for up to 24 hours past 2,500 MB down / 500 MB up in a day.
MailVault can warn you before a provider cuts you off โ or stop itself in time. A banner appears when an account passes 80% of its daily transfer limit, and an optional cap pauses syncing for the rest of the day before the limit is hit. Both are configurable per account in Settings โ Data Usage; Gmail accounts come with the known limits prefilled.
A Report a Bug button now sits next to Settings in the sidebar โ it opens a compose window with version and system details already filled in, under headed sections for what happened, how to reproduce it, and what you expected.
The sidebar's hover usage bubble can be switched off in Settings โ Data Usage, for anyone who would rather the sidebar stay quiet. The page's own breakdowns stay available.
Fixed
Quoted replies and signatures fold away in the single-email view too. Opening a reply showed the entire "Original Message" block with no way to collapse it โ the fold controls were only ever added to thread and chat view.
Clicking outside a reply no longer throws away what you typed. Replying or forwarding from an opened email, a thread, or chat view mounted its own compose window that couldn't minimize โ clicking outside closed it and discarded the draft. All reply and forward paths now use the same compose window, which minimizes to a bubble when you click away with unsent text.
v2.9.0August 4, 2026
Added
Your mail can now live wherever you want it โ an external drive, a NAS mount, any folder. Settings โ Backup shows where the working copy is stored and can move it: MailVault copies everything across, checks every file arrived, and only then removes the originals. If the drive is later disconnected, the app says so at the top of the main view and pauses syncing instead of quietly starting a second archive in its own storage; if the drive comes back at a different path, pick the folder again and MailVault verifies it is yours before carrying on. Going back to the default location asks whether to bring the mail with you โ move it back with the same copy-check-then-delete steps, or leave it in the folder and start fresh. (Developer ID and Linux builds for now.)
Fixed
Read, flagged and replied marks now survive a restore from the external backup. Backup copies were saved under a name that carried no message flags, so anything restored from them came back looking unread and unflagged. Backups now keep the full message name, and older flagless copies still restore as before.
Hitting a provider's daily download limit no longer grinds through thousands of doomed fetches. Gmail caps IMAP traffic per day (2,500 MB down, 500 MB up) and temporarily suspends accounts that exceed it โ for up to 24 hours, webmail included. Archiving and migration now recognize the server's "bandwidth exceeded" response, stop the run immediately, and say when to retry; everything already downloaded is kept.
The app no longer crashes at launch on Linux systems without a configured locale. On a system where the language environment is unset (LANG empty, common on minimal installs and servers), the browser engine reports the raw "C" locale, and every date formatter rejected it โ taking the whole window down to a "Something went wrong" screen before anything loaded. Date formatting now falls back to the system default when the reported locale isn't usable.
v2.8.0July 26, 2026
Fixed
Scrolling to the bottom of the list loads more mail again. If the background load ever stopped quietly โ a network blip at launch was enough โ the list froze at whatever it had (say 741 of 15,083) and scrolling did nothing: the scroll position was never actually watched, so reaching the end couldn't restart the load. Scrolling near the bottom now kicks it off directly.
Images embedded in an email show up again. Logos and signature images that a message carries inside itself rendered as empty boxes: the app fetches messages without their attachment data to keep things fast, so there was nothing to put in the image. It now loads just the embedded images from the message's local copy when you open it.
The message list header now says how much of the mailbox is actually in the list. It always showed the mailbox's total on the server, so a list that was still filling looked exactly like a finished one. It now reads "741 of 15,067 emails" until everything is loaded.
Adding an account with a non-standard mail-server port works again. Typing anything into the IMAP or SMTP port field made the connection test fail before it dialled โ the port was sent as text where a number was expected โ so only accounts on the default ports could be added.
Bulk operations can now select the whole mailbox, not just what's on screen. Picking "All" in Bulk Email Operations only covered the messages the list had scrolled in so far โ on a 15,000-message inbox that was a few hundred โ even though the app already held every message locally. It now selects from the full local copy of the mailbox, and skips messages you have already deleted.
Switching back to an account is instant now. The message list restarted at โ500 of 15,065โ and counted up again on every switch, because the app rebuilt the list by reading one file per message off disk โ fifteen thousand of them โ even though it had just had them all in memory. It now keeps the last few mailboxes it showed you, and when mail has arrived while you were away it re-reads only the messages that actually changed rather than starting the whole list over.
Loading a large mailbox no longer crawls. Filling the list read every message file in the mailbox over again on each step โ fifteen thousand of them, several times a second โ so the count climbed a little at a time with long pauses and looked stuck. It now reads only the messages it doesn't already have.
The message list no longer stops partway through loading and sits there. After switching accounts it could stick at a few hundred messages โ spinner showing, nothing actually downloading โ until you hit refresh. Two parts of the load raced over the same "still loading" flag, and the quick server check added in this release made the wrong one win.
The email counter no longer counts backwards. The โx / y emailsโ indicator measured how much of the list was on screen, which drops every time you switch accounts, so a switch looked like a fresh download. It now shows how much of the mailbox has been downloaded โ a number that only goes up โ and stops spinning when nothing is actually downloading.
Switching accounts no longer restarts the whole load. Every switch ran a full server sync and waited on it, even for an account you had opened moments earlier, and it restarted the background download of every other account's mail from the beginning. The app now asks the server whether anything actually changed โ one quick check instead of a full sync โ and picks up background work where it left off rather than starting over.
A backup that succeeded is no longer reported as failed. The prompt shown after a backup finishes could error and drag the completed backup down with it, marking it failed and quietly re-running it up to three more times.
A dropped connection can no longer wipe cached mail. If the server closed the connection while listing a mailbox's messages, the list came back empty with no error โ and the empty list was treated as "everything was deleted". The listing is now checked against the server's own message count and refuses to report a partial result.
Changing only the port of an account's mail server no longer reuses the old connection. Connections were pooled by address alone, so a config that differed only by port was handed a connection to the previous server.
Large mailboxes no longer get stuck loading forever on some servers. Listing the messages in a mailbox used one very long server reply, and on a 15,000-message mailbox some servers (Purelymail among them) interrupt that reply with a keep-alive line, which made it unreadable. The listing now arrives one message per line, so an interruption can't corrupt it.
A failed lookup can no longer blank your cached mail. When that reply failed to parse, the leftovers stayed in the connection and the next command read the wrong answer โ reporting an empty mailbox and deleting hundreds of cached messages. Connections are now dropped after a failed command instead of being reused.
A mailbox whose background fill fails now loads normally instead of spinning. The app waits while the helper fills a partly cached mailbox; if that fill failed, the wait never ended and the list kept loading with nothing actually downloading. The app now falls back to loading pages itself.
Mail connections are closed properly when you quit. The app and the background helper now log out of every open server connection on exit, instead of leaving them for the server to time out.
Email light/dark switching works again in installed builds. The app's security policy was tightened at build time in a way that blocked the script that darkens email content, so the Light/Dark button and the email theme setting did nothing โ the button changed state, the email stayed light. Opening the same email in its own window was unaffected, which is why it looked intermittent.
A mailbox that is only partly cached now fills itself in, once. After a restore or a server migration the local cache could hold a few hundred messages of a 15,000-message mailbox while still looking fully in sync โ so every launch dragged the missing thousands off the server, a few hundred at a time, and rarely got to the end before the app was closed. The background helper now notices the shortfall and downloads only the missing headers, newest first, while you keep using the app.
Loading a large mailbox no longer slows down the further it gets. Each batch of messages used to re-save every message loaded so far, so a full 15,000-message load performed well over half a million file writes. Only the new batch is written now.
Your other accounts no longer re-download their whole mailbox at startup. Background loading for non-active accounts (and the Sent folder of the active one) fetched every page from the server on every launch, ignoring the cache entirely. It now syncs the same incremental way the active mailbox does.
The background helper is reachable again. The app was looking for the helper's connection socket in the wrong folder, so every request to it failed and Settings always reported "Helper Not Running" โ even while the helper was running normally. Affected contact indexing, AI classification, snapshots and background sync since 2.7.0.
App restarts no longer re-download the mailbox. Saving headers used to delete every cached message that wasn't in the on-screen window, so an ordinary save cut a 14,000-message cache down to 500 โ and the rest was then re-fetched from the server page by page, roughly 70 IMAP round-trips on every launch. The cache is now treated as a superset of the loaded window and only drops messages that are actually gone.
Read, unread and star changes now survive a restart. Header cache writes skipped files that already existed, so a flag change updated the list but never reached disk and the old state came back on the next launch.
Background sync now fetches only what changed โ the messages that arrived since the last sync, plus flag updates โ instead of re-fetching the newest 500 headers every time. Sync metadata is also no longer wiped by routine cache saves, which had been silently forcing that full fetch.
Scrolling back through a large mailbox now reads from the local cache instead of re-fetching pages from the server.
Deleted emails are pruned from the local cache on a count mismatch and, as a backstop, on a periodic full reconciliation โ so a message deleted from another device can no longer linger in the list.
Messages the server has flagged as deleted but not yet removed are now hidden from the list. Messages archived to your local vault stay visible either way.
Emails no longer reappear as duplicates or ghosts after a server rebuilds its message IDs (UIDVALIDITY change) โ the stale generation is now cleared instead of merged with the new one.
Read and star state now refreshes on servers that don't support CONDSTORE, which previously left cached messages showing stale flags indefinitely.
Deletions made in Outlook/Microsoft 365 accounts are now removed from the local cache instead of reappearing on the next load.
The Sent folder for Outlook/Microsoft 365 accounts is no longer capped at 200 messages.
Loading more messages could skip about 100 emails when the list was seeded from the cache; pages now overlap and de-duplicate instead.
Internal
Removed a second, unused email cache implementation (mailvault_core::cache) and the 14 daemon RPCs that fronted it โ nothing called them, and the app has always read the sidecar cache through Tauri.
A failed background sync no longer leaks its IMAP connection back into the pool.
v2.7.0July 24, 2026
Added
Change-server restore can now be minimized to a corner bubble: the upload keeps running in the background, the bubble shows live progress, and clicking it reopens the modal (Escape mid-restore also minimizes instead of being blocked).
Thread view: clicking a sender's name or avatar now opens the same Sender Details popover as chat view (full address, To/CC, verification, mailing-list "via").
Restore-to-server: when an account's IMAP host is changed to a new, empty server, the app detects that the local Maildir still holds the account's mail and offers to re-upload it (all folders, flags preserved, dedup-safe re-runs).
Guided Change Server flow: dedicated 3-step modal replacing the old Settings-only server edit. Enter new IMAP/SMTP hosts and the new password in one form โ hosts are pre-filled by DNS auto-detection (SRV/autoconfig/MX), with a warning when your domain's DNS still points at the current server. Both IMAP and SMTP are verified (new smtp_test_connection command) before anything is saved. After saving, the app offers to upload locally stored mail to the new server, then runs a DNS health check (MX/SPF/DKIM/DMARC, new dns_mail_health command) and warns if mail delivery would be affected.
Mac App Store build target: New appstore Cargo feature, tauri.appstore.conf.json overlay, and Release (Mac App Store) GitHub Actions workflow. Build locally with npm run build:appstore; CI builds + signs + uploads via App Store Connect API. See BUILDING.md for required secrets and gotchas.
In-app purchase gating for Cloud Backups (MAS only): External backup folders are now gated behind a non-consumable StoreKit IAP (com.mailvault.app.backups) in App Store builds. New iap_* Tauri commands bridge to SKPaymentQueue/SKMutablePayment via objc2-store-kit; entitlement is persisted in NSUserDefaults. Non-MAS builds are unaffected โ the IAP module is stubbed out and always reports entitlement.
Paywall UI in Backup settings: BackupConfig.jsx shows a one-time purchase prompt with a Restore button when running an unentitled MAS build.
Changed
Sparkle auto-updater is now an opt-in Cargo feature (sparkle, on by default). MAS builds drop the plugin, the Sparkle.framework, the "Check for Updatesโฆ" menu item, and the background update check โ App Store handles updates instead.
Sidebar connection-error card: "Change server" now opens the guided flow directly; "Migrate mail" removed from the card (the migration wizard needs a working source server โ it remains in Settings โ Migration). The expanded-sidebar card variant now also offers "Change server" (it previously only appeared in the collapsed variant).
Fixed
Deleting emails (single or multi-select) did nothing on servers whose Trash folder lives in a namespace (e.g. Hostinger/Dovecot INBOX.Trash): the delete now resolves the real Trash mailbox via SPECIAL-USE/LIST (auto-creating one if missing) instead of guessing hardcoded names, and falls back to COPY + EXPUNGE on servers without MOVE. Previously the message was only flagged \Deleted and reappeared on reload.
Deleted emails no longer resurrect from the local header cache. Moving mail to Trash bumps the server's CONDSTORE modseq without changing UIDNEXT, and the flag-only fast sync path cannot see expunges โ deleted emails kept reappearing on reload/restart even though the server delete succeeded. The fast path now verifies the server message count and falls through to full UID reconciliation when it changed.
Fixed an IMAP session desync that could blank an entire folder view: some servers' (e.g. Purelymail) ESEARCH responses fail to parse in our IMAP library, leaving the connection misaligned so every subsequent command read the previous command's reply โ a delete followed by a sync then wrongly concluded the mailbox was empty. The ESEARCH fast path was removed (plain UID SEARCH ALL everywhere) and the app now refuses to prune the email list when a search claims "empty" while the server reports messages.
Deleted emails now disappear from the list instantly on confirm; the server deletion runs in the background and any email whose server delete fails is restored on the follow-up sync.
Deleted emails no longer flash back when switching accounts or folders while the server deletion is still in flight (session-scoped delete tombstones filter them out of every list render until the cache is reconciled).
Thread view: the sender-details/verification popover is no longer clipped when opened on a collapsed message row.
Unrelated automated emails with identical subjects (forum digests, contact-form notifications) are no longer merged into one giant thread. Subject-based thread merging now only applies to Re:/Fwd:-prefixed messages that lack threading headers; proper References/In-Reply-To chains still thread as before.
Post-server-change DNS health check no longer flags a missing DKIM record for domains using Purelymail (added purelymail1-3 and other common selectors), and the warning now says the check is inconclusive rather than claiming DKIM is absent.
Changing servers when the stored password is missing or stale no longer dead-ends: the connection test now uses the newly entered password instead of the stored one.
Background-sync daemon now returns the same flat mailbox list as the app, fixing accounts on some providers (e.g. Hostinger) appearing to have only one folder in daemon-driven flows (fixed as part of consolidating the duplicated IMAP client โ see Internal).
Removed
Bun-compiled mailvault-server sidecar deleted. All IMAP/SMTP/OAuth2 logic already lived in the Rust Tauri process; the Node sidecar was dead weight (last frontend caller โ src/workers/emailCacheWorker.js โ was unreferenced). Drops ~30 MB from the bundle, eliminates the JavaScriptCore JIT entitlement requirement that was blocking MAS review, and removes dependencies on express/cors/helmet/imapflow/mailparser/nodemailer/express-rate-limit + Bun toolchain. OAuth2 loopback callback now bound by src-tauri/src/oauth2.rs on 127.0.0.1:19876.
Internal
Codebase-wide dead-weight purge (~5.2k lines removed): duplicated IMAP/Graph/OAuth2/DNS modules consolidated from src-tauri + src-daemon into the shared mailvault-core crate (the two copies had already drifted); never-compiled helper.rs deleted; dead Tauri commands, dead frontend modules/exports, and unused dependencies removed (uuid, @tauri-apps/plugin-http, thiserror, log, once_cell โ std::sync::LazyLock, tauri-plugin-http); daemon tokio features trimmed.
Oversized frontend modules split on existing seams with zero behavior change: activateAccount.js โ one-workflow-per-file, db.js โ db/ submodules behind a facade, GeneralSettings.jsx โ per-subtab components, ChatBubbleView.jsx modals extracted.
iap.rs module + MV_IAP_DEV_ENTITLE=1 env override for local testing of the paywall flow.
entitlements-appstore.plist now omits Sparkle XPC mach-lookup keys.
entitlements.plist no longer includes JIT entitlements (cs.allow-jit, cs.allow-unsigned-executable-memory, cs.disable-library-validation) โ they were only needed by the removed Bun sidecar.
Row delete confirmation: The 3-dots row menu's "Delete from server" no longer relies on an unreliable inline two-click confirm inside the virtualized row. Confirmation is now lifted to a portal-rendered modal at the list level so it escapes the virtualizer's transform stacking context and works consistently across the default and compact email/thread rows.
Fixed
MIME-encoded subjects with non-conformant whitespace: Subjects like =?utf-8?Q?Dovan=C4=97l=C4=97_?=naujagimiui ir mamai (encoded-word adjacent to plain text without RFC-required separating whitespace) now decode correctly in the email list and thread view. Replaced strict mailparse-based decoder with a lenient RFC 2047 scanner shared between the desktop app and daemon (mailvault_core::mime::decode_rfc2047). Full-mail Subject extraction now reads get_value_raw() and routes through the same decoder.
v2.5.0April 27, 2026
Added
Outbox tray + local stage-then-send: Compose now archives to local Maildir before SMTP send; new outbox tray surfaces in-flight sends with cancel and retry; Shift+Enter sends; configurable per-compose send delay
Per-account Sent folder resolution: Tiered SPECIAL-USE โ name-heuristic โ lazy CREATE detection with auto-heal so sent emails reliably land in the right Sent folder per account
Contacts picker popover: Per-account filtered + boosted contact suggestions in compose; 15s reload throttle; daemon-side contacts indexing across INBOX, Sent, and custom folders (with frontend disk-walk fallback)
Reply-To mismatch alert: New ReplyToAlertIcon flags emails whose Reply-To header diverges from the From address โ common phishing tell
Email viewer dark mode v5: Inlined DarkReader with body-only scan, per-email toggle, and new emailViewerTheme setting that decouples app theme from email rendering theme
Maildir .eml suffix + migration: Stored email files now carry the .eml extension for OS-level interoperability; daemon performs a one-time version-guarded rename of legacy filenames on startup
Improved
Link safety modal: Portal-rendered so it escapes virtualized-row transform ancestors and sits correctly over the viewport
Selection action bar: Narrow-screen layout fit and pointer-events fix on the delete confirmation popover
Account activation: Guards against wiping email state on background refresh paths
Dev script: Daemon socket and lockfile path aligned at ~/.mailvault/mv.sock for sandboxed/sidecar parity
Settings menu: Sidebar restructure continues โ feature views (Email Cleanup, Time Capsule) consolidated under settings
Fixed
Sent IMAP APPEND hang on Hostinger: Added pool-checkout and append-verified breadcrumbs; Message-ID parser rewritten for CRLF; secondary IMAP append spawned instead of awaited so a stalled secondary cannot block the primary send response
Compose Escape behavior: Escape now mirrors backdrop click (minimize to outbox bubble) instead of popping a discard prompt
Iframe load race / cache scope: Fixed intermittent "blank email" caused by iframe load-event race and cache-key scope mismatch
macOS WKWebView dark scrollbars: Themes now declare CSS color-scheme so scrollbars render correctly on dark backgrounds
WKWebView file:// charset: Email HTML loads with UTF-8 BOM + meta charset first to avoid Latin-1 default decoding
Stacked keychain prompts: Removed second uncancellable spawn_blocking retry path that produced a duplicate macOS keychain dialog
v2.4.0April 16, 2026
Added
Email Cleanup settings view: Moved Email Cleanup from sidebar into Settings as an inline feature view with Naive Bayes classification controls
Time Capsule settings view: Moved Time Capsule from sidebar into Settings as an inline feature view
Snap publish gating: Release pipeline no longer auto-publishes snaps; new Promote Snaps workflow for manual publish after testing
Configurable send delay: Per-compose send delay override (15sโ5min) with global default in settings
Sent folder sync: Copy sent email to IMAP Sent folder after SMTP send
Improved
Email classification: Replaced heuristic-based classification with Naive Bayes classifier for more accurate email categorization
Email list performance: Extracted EmailRow and ThreadRow into standalone memoized components
Settings architecture: Restructured settings into modular subcomponents for better maintainability
Background helper architecture: Extracted daemon management into dedicated helper.rs module separating launch strategy from RPC transport; UI reworded from "system service" to "background helper"
Fixed
Outlook/Graph email content mismatch: Clicking one email could display a different email's content โ synthetic positional UIDs drifted when email order changed between fetches; Graph message ID now embedded directly on each email header
Cross-account email bleed: Switching folders showed stale emails from the previous account when the target folder was empty โ all email state is now cleared atomically on account/mailbox switch
Daemon sandbox socket: IPC socket moved to ~/.mailvault/mv.sock via dirs::home_dir() so both the sandboxed app and sidecar daemon resolve the same container-relative path
Daemon entitlements: Removed app-sandbox from daemon (crashes standalone binaries without Info.plist); removed application-groups (not needed with shared container home)
Release signing: $(AppIdentifierPrefix) in entitlements is now expanded before codesign โ fixes silently broken keychain sharing between app and daemon
Module cache invalidation: Clear module-level caches on invalidation, cap unified folder cache, remove redundant descriptor saves
Account activation: Prevent infinite recursion in activateAccount descriptor restore path
Store architecture: Remove state-duplicating domain store wrappers, use thin selector re-exports
v2.3.2March 29, 2026
Fixed
macOS external backup crash: Fixed wrong Objective-C selector (relativeToBookmarkURL โ relativeToURL) in security-scoped bookmark resolution that caused SIGABRT when selecting or validating an external backup folder on macOS
Bookmark lifecycle hardening: All macOS Objective-C bookmark calls wrapped in catch_unwind so malformed bookmarks degrade to "needs reauthorization" instead of crashing the app
v2.3.1March 29, 2026
Added
External backup failure reporting: IMAP and Graph backup runs now track external-copy failures separately โ local backup succeeds independently while external failures are captured with per-email counts
Degraded backup status in UI: Backup Settings shows amber "Partial" state for runs where local backup succeeded but external copy failed, distinct from full success and total failure
Version consistency check: New check-version-consistency.sh script runs in CI to catch version drift across package.json, Cargo.toml, tauri.conf.json, and snapcraft.yaml
Fixed
macOS sandbox external backup: External backup folder access now uses security-scoped bookmarks that persist across app restarts; legacy raw paths are detected and prompt reauthorization
Linux Snap external backup: External backup validates actual write access under Snap confinement instead of assuming paths are writable
Backup verification bypass: "Check backup coverage" no longer reads the legacy backupCustomPath โ uses native bookmark-resolved path like the rest of the backup system
Silent external write failures: External fs::write and create_dir_all failures in IMAP archive and Graph backup are now captured and reported instead of silently ignored
Stale Snap version: snapcraft.yaml fixed from 2.1.3 โ 2.3.1; bump script rewritten with pattern-based replacement so drifted files are corrected instead of silently skipped
Display name quoting: Fixed quote stripping for names with mixed Unicode/ASCII quotes; name upgrade logic replaces email-derived local parts with proper display names
CI e2e build: Added stub binary for Linux, fixed binary name mismatch, increased timeout
v2.3.0March 28, 2026
Added
Premium subscriptions via Stripe: Monthly (โฌ3) and yearly (โฌ25) plans with Stripe Checkout, webhook processing, Customer Portal, and a new Billing tab in Settings with plan cards, feature comparison, and subscription management
14-day free trial: Yearly plan includes a 14-day free trial for new customers; trial eligibility is server-driven and one-per-customer; monthly plan remains paid immediately
Multi-currency billing: EUR base pricing with fixed USD and GBP options; Stripe Adaptive Pricing for other currencies; server-driven pricing endpoint so displayed prices always match checkout
5-device subscription limit: Per-install client registration with automatic oldest-device replacement when a 6th device connects; device usage bar and active client list in Billing settings
Sparkle auto-updater (macOS): Native Sparkle 2 framework integration for sandboxed macOS builds โ automatic update checks, download, and quit-time installation via XPC services
Backup verification view: Folder-level tree table in Backup Settings showing Server / App / External counts per folder with expand/collapse, summary chips, and progress bar โ works for both IMAP and Outlook/Graph accounts
Backup icon opens focused account: Clicking a sidebar backup status icon opens Settings on the Backup tab and scrolls to that account's card with a transient accent ring highlight
Empty-cache corruption prevention: Suspicious empty server results are now rejected when prior cache had data โ preserves mailbox trees and email headers with last-known-good recovery, IMAP verification pass, and sidebar warning banner
Improved
Billing rate-limit protection: Single-flight status checks with 60s auto / 10s manual cooldowns, split server rate limiters by route, 429 handling with Retry-After, in-memory server-side response cache
Shared credential resolver: Mail loading and backup share a single resolveServerAccount() helper โ eliminates duplicate credential-check paths; Graph accounts get JWT validation and forced refresh everywhere
Keychain access: Single-prompt model โ at most one OS keychain prompt per session; if denied/cancelled/timed out, no background re-prompts; app stays usable with cached/local data
Backup scheduler: Lifecycle-aware coordinator with proper state machine, time-of-day and day-of-week scheduling, gates that prevent backup during active use, and resumable folder-level checkpoints
Sidebar performance: Isolated backup progress into ephemeral store, narrowed store subscriptions, memoized per-account rows
Display name handling: Fixed quote stripping for names with mixed Unicode/ASCII quotes (e.g. Lithuanian company names); name upgrade logic now correctly replaces email-derived local parts with proper display names
Fixed
Graph/Outlook external backup: run_graph_backup now writes emails to both app Maildir and external backup directory; adds bidirectional pre-sync per folder
Outlook credential recovery: resolveServerAccount() accepts keychain accounts with malformed access tokens if they have a refresh token, then force-refreshes
Outlook OAuth reconnect: Settings reconnect now passes useGraph, customClientId, and tenantId to getOAuth2AuthUrl()
Graph/Outlook token handling: Reverted hasValidCredentials() to presence-only check โ Microsoft Graph can return opaque non-JWT tokens that are valid
Manual backup false success: "Back up now" button no longer shows Done! when backup was skipped due to missing credentials
Keychain retry loops: Removed JS-side retry loop and automatic re-prompt; structured response returns status instead of raw HashMap
Outlook sidebar badge: Successful backup no longer shows amber warning when slightly overdue
Backup coverage check: Fixed missing api import that caused runtime error
v2.2.1March 13, 2026
Added
Sender-grouped view: New toggle in email list toolbar groups emails by sender โ topics โ individual emails in an accordion layout
Dedicated mailbox cache: Mailbox list cached separately per account for instant folder loading
App-specific password help links: iCloud and AOL provider notes now include direct links to generate app passwords
Improved
Mailbox loading performance: Local email index cache (local-index.json) eliminates .eml MIME parsing on load; progressive chunked rendering shows emails instantly with background loading; switching mailboxes/accounts cancels in-progress loads via AbortController
Fixed
Startup crash: Removed Sparkle updater framework that caused dispatch_sync deadlock crash on macOS launch; custom appcast updater remains fully functional
Unified inbox: Fixed local/archived emails not showing for accounts with overlapping UIDs in unified view
v2.2.0March 11, 2026
Improved
Email loading: Refactored to two-stream architecture โ local cache and server data load in parallel via activateAccount(), replacing 6 overlapping phases with a clean Promise-based model; eliminates "empty emails" bug on rapid account/mailbox switching via AbortController cancellation
Codebase refactor: Extracted Graph config, LRU caches, search, and performance tracing into dedicated modules; SettingsPage and EmailViewer split into focused sub-components; bulk operations presets reordered by duration (Today โ All)
v2.1.5March 11, 2026
Fixed
Linux window activation: Clicking app icon while already running now brings window to front via SIGUSR2 signal between instances (previously second instance exited silently)
Improved
Compose modal: Larger compose window (max-w-4xl, 80vh height) for more writing space; unsaved changes confirmation prevents accidental dismissal
v2.1.4March 11, 2026
Fixed
macOS updater: Replaced Sparkle XPC installer with custom appcast-based updater โ checks GitHub releases, shows in-app update modal with direct DMG download link; eliminates "An error occurred while launching the installer" permanently
v2.1.3March 11, 2026
Fixed
macOS updater: Added SUEnableInstallerLauncherService to Info.plist โ required for sandboxed Sparkle updates; fixes "An error occurred while launching the installer" on v2.1.1+
Linux single instance: Enforce single app instance via flock kernel lock โ prevents email disappearance caused by multiple concurrent instances; works across AppImage, .deb, Snap, and Flatpak
IMAP error messages: Show actual IMAP error instead of generic "Failed to connect" when adding accounts
v2.1.2March 11, 2026
Fixed
Snap updater: Detect snap environment and show "Updates managed by Snap Store" instead of cryptic "builder error"; .deb installs show helpful message directing to website
Linux error messages: Fixed generic "Failed to connect to email server" when actual IMAP error was available โ Tauri invoke errors are strings, not Error objects
v2.1.1March 10, 2026
Changed
macOS updater: Replaced broken Tauri updater with Sparkle 2 framework โ native macOS update UI, sandbox-safe XPC installer, EdDSA-signed appcast.xml; Linux keeps tauri-plugin-updater with custom UpdateModal
v2.1.0March 10, 2026
Added
Custom update modal โ replaced native OS update dialog with a styled in-app modal showing full changelog, download progress bar, and three dismiss options: "Update Now", "Remind Me Later" (24h snooze), and "Skip This Version"
Keyboard shortcuts for all core actions (navigation, compose, reply, archive, delete, move) with customizable bindings, cheat sheet modal (?), and settings UI for rebinding
Move to Folder โ move single or bulk-selected emails between server folders via IMAP MOVE/COPY with undo support; Graph API support for Microsoft accounts
Undo Send โ configurable delay (5/10/15/30s) before dispatching emails, with countdown toast and one-click cancel to reopen compose
Unified Inbox โ merged chronological view of all accounts' inboxes with per-account colored indicators and correct reply routing
Notification customization โ per-account and per-folder notification controls with privacy-aware preview toggle (show sender+subject or generic message)
Email templates โ save, manage, and insert reusable email snippets when composing, with save-as-template from any draft
Smart Sender Insights โ collapsible panel in email viewer showing exchange history, frequency, common topics, and accounts used per sender
Auto-Cleanup Rules โ automated email cleanup by age and folder with archive-then-delete or delete actions, dry-run preview, and 24-hour scheduling (Pro feature)
Improved
Performance โ unified inbox loads instantly from disk cache on launch; account cache increased to 8 with pre-warming from headers.json; chat view uses deferred threading, React.memo, and virtualization; layout switch uses debounced ResizeObserver
Folder caching โ mailbox folders persist to disk and restore instantly on cold launch; background IMAP refresh updates silently; removed folder expand/collapse animation for snappier UI
Email content fallback โ retry with exponential backoff when body loading fails; graceful degradation shows email text/snippet instead of error message
Fixed
Loading guard scope โ moved 20-second loading timeout to cover entire loadEmails function including credential and network checks, preventing stuck spinners during early failures
Unified Inbox โ fixed all email operations (select, read/unread, delete, move, archive, export) passing virtual "UNIFIED" mailbox to IMAP instead of resolving the real account and INBOX; fixed stale content flash when entering/leaving unified view; fixed account switch from unified inbox showing combined emails instead of individual account; fixed "All Inboxes" header persisting after leaving unified view
Account switching โ fixed selecting an account from unified inbox doing nothing when it was the previously active account; fixed invalid remembered mailbox (deleted/renamed folder) causing blank screen โ now falls back to INBOX
Snap Store โ added CA certificate bundle and SSL environment variables to fix "Failed to connect to email server" in strict confinement
v2.0.3March 8, 2026
Fixed
Loading guard scope โ moved 20-second loading timeout to cover entire loadEmails function including credential and network checks, preventing stuck spinners during early failures
Bug report email โ "Report Bug" button in Settings > Help & Support and in the app menu; opens a pre-filled compose window with system info (version, OS, account count, provider) and structured bug report template, sent to the developer
DNS-based email auto-detection โ when adding a custom-domain account, the app now resolves SRV records (RFC 6186), Mozilla autoconfig XML, and MX records to automatically detect IMAP/SMTP server settings; includes known provider mapping (Google Workspace, Microsoft 365, Hostinger, Zoho, Yahoo, Fastmail, ProtonMail) with pattern-guess fallback
Email list info bar โ folder header now displays total email count, current view mode (All/Server/Local), and date range of loaded emails
Progressive archive icons โ email list icons now update in real-time during batch archive as each email is saved, instead of waiting for the entire operation to complete
Fixed
Bulk save toast โ "Operation complete" notification now auto-dismisses after 4 seconds on success; X button available for immediate dismiss; error completions stay visible until manually closed
Account modal dismiss protection โ clicking outside or pressing Escape while adding an account now shows a confirmation dialog if any data has been entered, preventing accidental loss of typed details
Folder name display โ stripped INBOX. prefix from folder names in sidebar (e.g., "INBOX.Trash" now displays as "Trash"); internal folder paths unchanged
Email content responsiveness โ single-email view now uses the same responsive iframe sizing as thread view, with proper overflow handling for wide tables, images, and preformatted text
Sidebar scrollability โ accounts section is now independently scrollable with a 30% max height cap, ensuring folders remain visible even with many accounts
Startup loading spinner โ fixed stuck loading spinner on app launch when cached emails exist; added safety guard in init() and 20-second timeout failsafe
Export backup clarity โ removed confusing "All Local Emails" option from export backup modal; only the "Archived Emails" export remains
v2.0.1March 7, 2026
Fixed
macOS updater โ added sandbox entitlement for writing to /Applications/, allowing in-app updates to complete successfully
Linux support โ MailVault now runs natively on Linux (x86_64 and aarch64) with .deb and AppImage packages; credentials stored via D-Bus Secret Service (GNOME Keyring / KWallet); native Wayland and X11 support; CI builds macOS + Linux in parallel
Linux app menu โ File menu with Check for Updates, Settings (Ctrl+,), and Quit (Ctrl+Q); Logs menu with Export Logs
Fixed
Memory reduction โ lowered default body cache from 512 MB to 128 MB, reduced account/mailbox LRU cache sizes, excluded derived data from cache snapshots; targets ~200-300 MB total memory (down from ~1.14 GB)
App updater โ "Update Now" button now shows a downloading indicator and displays error dialogs on failure instead of silently doing nothing
Email list overlap โ action buttons (archive, menu) no longer overlap text when the email list panel is narrow; buttons now float over the row on hover
macOS-only Reopen event โ fixed compilation error on Linux where RunEvent::Reopen is macOS-only
v1.9.2March 4, 2026
Added
Quote folding โ quoted reply content (> lines, "On wrote:", Original Message blocks, HTML blockquotes) is detected and collapsed behind a clickable toggle in both thread view and chat view; collapsed by default for cleaner reading
Signature folding โ email signatures detected and handled with configurable display mode: Smart (show once per sender per thread, collapse duplicates), Always Show, Always Hide, or Collapsed with toggle; configurable in Settings > Appearance
Sender verification badges โ two-layer sender spoofing check: header mismatch detection (From vs Reply-To/Return-Path domain) and email authentication parsing (SPF/DKIM/DMARC from Authentication-Results header); shows green shield for verified, orange warning for Reply-To mismatch, red warning for authentication failure
Thread sort order โ configurable setting to sort thread emails oldest-first or newest-first; available in Settings > Appearance
Thread email details โ expanded header info (Message-ID, Reply-To, full date) and View Source button now available in thread conversation view, matching single email view
Fixed
Attachment downloads on IMAP accounts โ fixed "Email UID not found" error when downloading attachments; .eml files were being saved under the email-address directory instead of the account UUID directory, causing a path mismatch on read; includes one-time migration of orphaned files
Embedded inline images โ CID-referenced images (e.g. logos, inline photos) now render correctly in email body by replacing cid: URLs with inline data URIs; applies to single email, thread, and chat views
Export/import progress โ backup export and import now show a non-blocking progress modal with real-time file count instead of a button spinner; export choice dialog uses clearer wording ("Archived Emails" / "All Local Emails")
Faster folder loading โ mailbox folder list is now cached and loaded instantly on app startup and account switch; server refresh happens in background without blocking the UI; all visible accounts' mailboxes are pre-fetched on startup
v1.9.1February 28, 2026
Added
Microsoft Graph API transport โ personal Outlook.com/Hotmail/Live.com accounts now use Graph REST API instead of IMAP, bypassing the known Microsoft IMAP server-side regression; auto-detected by email domain; supports read, delete, and mark read/unread
Own Azure AD app registration โ replaced borrowed Thunderbird client ID with MailVault's dedicated Azure AD app for more reliable corporate M365 OAuth2 authentication
Advanced OAuth2 fields โ corporate Microsoft users can now specify a custom Client ID and Tenant ID for organizations with strict OAuth2 policies
Fixed
Thread view loading โ fixed race condition where email content showed "Could not load" until manually collapsed/expanded; bodies are now pre-populated synchronously before first render
v1.9.0February 26, 2026
Fixed
Date alignment in email list โ date no longer shifts position when archiving emails (fixed-width hover action area)
Keychain access โ keychain dialog now appears without freezing UI (async Rust); retry button uses correct credentials format with cache reset; auto-retries after 5s if keychain was slow; clear "Password missing" error with direct Settings link when credentials are lost
Added
Year display for old emails โ previous-year emails now show the year (e.g., "Feb 25, 2024")
Locale-aware date formatting โ uses system region by default; configurable in Settings > Appearance with presets (US, European, ISO, short) and custom date-fns pattern support
Instant account switching โ LRU cache (max 5 accounts) saves/restores full email state on account switch; eliminates empty-list flash and avoids re-reading 15-20MB headers.json from disk
Parallel background header loading โ background accounts now load INBOX + Sent headers immediately alongside active account content caching (previously blocked until active finished); mailbox lists pre-fetched for instant folder switching on account change
Email body pre-fetch โ next 3 email bodies pre-fetched in background after selecting an email for instant navigation
CONDSTORE fast-path โ skip redundant disk reads for savedEmailIds/archivedEmailIds when account cache is fresh (< 5 minutes)
Improved
IMAP fetch batch size โ increased from 50 to 200 emails per page, reducing round-trips from 340 to 85 for a 17k mailbox
Bulk operations โ archive-and-delete and bulk delete with concurrent IMAP operations (5 workers), progress tracking, cancel support, and crash-safe pending operation recovery on next launch
Selection action bar โ floating action bar for bulk email selection with archive, delete, mark read/unread actions
Sidebar refresh button โ manual refresh button in sidebar footer (both expanded and collapsed states) with animated spinner during sync
Pull-to-refresh โ pull down on email list to trigger a manual refresh
Mailbox LRU cache โ switching between mailboxes (INBOX, Sent, Drafts) is now instant; last 3 mailbox states cached in memory with automatic LRU eviction
Instant archived email display โ archived emails stored on disk now appear in the email list within ~400ms (previously 4+ seconds); 3-tier loading strategy: sidecar cache, archived headers cache, .eml fallback with progressive batch display
Chat view: attachment support โ chat bubbles and the full-view modal now show functional attachment cards (click to download/open, right-click for Open/Open With/Save As/Show in Folder); uses compact styling to fit the chat bubble aesthetic; correctly resolves mailbox for both inbox and sent folder emails
IMAP performance optimizations โ 9 optimizations to IMAP header loading: UID range compression (reduces command size from O(n) to O(ranges)), chunked UID FETCH (200-batch limits prevent command-length errors), lean fetch spec (drops BODYSTRUCTURE/RFC822.SIZE from header loads), newest-first UID fetching (users see newest emails first during delta-sync), COMPRESS=DEFLATE negotiation (70-80% bandwidth reduction when server supports it), capability caching in connection pool, skip-redundant-SELECT tracking, CONDSTORE delta sync (zero IMAP calls when mailbox unchanged, flag-only sync when only flags changed), and ESEARCH for compact UID enumeration
Email list scrolling performance โ fingerprint-based memoization skips redundant O(n log n) sorts in updateSortedEmails() and getChatEmails(); individual Zustand selectors prevent cascade re-renders from background pipeline updates; hand-rolled virtual scroll with static CSS positioning for smooth 17k+ email scrolling
Concurrency & pipeline performance optimizations โ 10 optimizations: Set-based uncached UID filtering (eliminates 17k sequential IPC calls), parallel disk reads via Promise.all in loadEmails/setActiveMailbox/pipeline finish, batch maildir_read_light_batch Rust command (single IPC for all local emails), IMAP connection pool expanded from 1โ3 sessions per account (supports concurrent workers), parallel background account header loading (up to 3 accounts at once), memoized thread building, batch account backfill (single file read/write), reduced pipeline/pagination/loadMore delays (5sโ1s, 1sโ200ms, 2sโ500ms)
Fixed
View mode filtering (all/server/local) โ server view no longer empty on account switch; local view correctly distinguishes archived (green) vs local-only (orange) emails; all view shows correct source icons
Thread view date pushed off screen โ CSS contain: inline-size at multiple container levels prevents expanded email iframe content from stretching collapsed message headers; date stays visible at all window widths
Thread list date shifting on hover โ moved date inside subject flex container so hover action buttons don't displace it
Thread view missing archive icons โ each message in thread conversation view now shows source icon (cloud/green HardDrive/orange HardDrive)
Thread view iframe overflow โ email HTML content (wide tables, images) no longer expands beyond container
Badge count oscillating during IMAP sync โ dock badge no longer flickers between values as email pages load; debounced with 2s delay
Archived emails race condition โ localEmails no longer overwritten by IMAP sync; fire-and-forget chain is now the sole owner of localEmails state
Thread cache never working (crash fix) โ getThreads() checked _threadsCache.length but buildThreads() returns a Map (which uses .size); cache was always bypassed, causing expensive thread rebuilds on every render with 17k emails
Thread/compact row crash on null lastEmail โ added null guard to ThreadRow and CompactThreadRow to prevent crash when a thread has no emails during race conditions
findRoot stack overflow โ cycle detection in email threading now also tracks by UID, preventing infinite recursion on emails without Message-ID but with inReplyTo loops
Direct Zustand state mutation โ addToCache no longer mutates get().cacheCurrentSizeMB outside set(); uses module-level variable for sub-threshold tracking
Sorted emails fingerprint missed flag changes โ updateSortedEmails fingerprint now includes a flag-change counter so read/unread toggles are detected
loadEmailRange O(17k) loop โ replaced for (i=0; i loop with Array.from(entries).sort().map() โ now O(loaded) instead of O(total)
Sidebar/EmailViewer re-rendering on every store change โ replaced whole-store useMailStore() subscriptions with individual selectors in Sidebar and EmailViewer
Object selectors without shallow comparison โ split object literal selectors into individual selectors in ChatBubbleView MessageBubble, AttachmentItem, and DownloadAllButton to prevent unnecessary re-renders
selectedEmailIds Set cascading re-renders โ thread rows now receive precomputed anyChecked boolean prop instead of the full Set reference
ThreadEmailItemContent iframe rebuilt every render โ wrapped iframeContent string in useMemo keyed on loadedEmail?.html
60fps scroll handler re-renders โ throttled handleScroll via requestAnimationFrame to batch scroll state updates
IMAP NOOP on every pool get โ added time-based skip: sessions used within 60s skip the NOOP health check; added per-session last_selected tracking instead of per-account-key
Pipeline header loading 200ms artificial delay โ reduced to 50ms (just enough to yield to event loop), saving ~30s on 200-page mailboxes
waitForComplete/startContentCaching race โ reordered to call startContentCaching() before waitForComplete() to prevent synchronous completion firing before promise setup
Subject-fallback orphan merge โ orphans with matching subjects now merge with each other (not just with multi-email threads)
normalizeSubject called redundantly โ added module-level memoization cache for normalized subjects
ensureFreshToken called per-email in pipeline โ moved to before the worker loop with re-call only on auth errors
Large mailbox not loading (17k+ emails) โ fixed multiple issues: _sortedEmailsFingerprint not reset on account switch caused sortedEmails to stay empty via false fingerprint match; quick-load parsed full 15-20MB headers.json (now loads partial 200 headers); displayEmails redundantly re-sorted 17k emails (now uses pre-sorted sortedEmails directly); threadedDisplay depended on stable getChatEmails function ref that never triggered recomputation (added sortedEmails as dependency)
Large mailbox stall at partial cache โ CONDSTORE and non-CONDSTORE early-return paths in delta-sync now check whether the local cache is partial and schedule loadMoreEmails() when needed; previously, mailboxes with 17k+ emails would stall at ~200 cached headers because the "no changes" fast path returned without continuing background pagination
Endless spinner on app launch โ getChatEmails() was calling Zustand set() during React render (inside a useMemo), and threadedDisplay useMemo never reacted to sortedEmails changes because the function reference was stable; moved chat email cache to module-level variables
Pipeline manager _destroyed flag never initialized or reset โ destroyAll() now sets the flag, constructor initializes it, and startActiveAccountPipeline() resets it so background pipelines can run after a destroy/restart cycle
CONDSTORE flag-only sync false negative โ removed serverTotal === existingEmails.length condition that failed with partial caches; uidNext unchanged already guarantees no new messages
Thread cache stale after flag changes โ added _flagSeq store state and _flagChangeCounter to getChatEmails/getThreads/EmailList thread fingerprints so read/unread and archive changes propagate to thread views
waitForComplete() hang on pipeline destroy โ stored resolve callback for destroy() to call; made waitForComplete() idempotent with shared promise
All accounts hidden crash โ added null guard for firstVisible in init() when all accounts are hidden
findRoot O(Nยฒ) chain walking โ added memoization cache so each email's thread root is computed once, not re-walked from scratch
Thread delete triggers N loadEmails calls โ added skipRefresh option to deleteEmailFromServer; thread delete handlers now batch deletions and call loadEmails() once
Dynamic Zustand store key leak โ replaced _rangeRetry_* dynamic store keys with module-level Map for range retry state
Archive state stale in chat view โ getChatEmails fingerprint now includes archivedEmailIds.size
IMAP pool sessions always re-SELECT โ with_background/with_priority helpers now pass the selected mailbox back to the pool for session reuse tracking
App.jsx and usePipelineCoordinator re-renders โ converted whole-store subscriptions to individual Zustand selectors
Stale rAF scroll position โ fixed handleScroll to read scrollTop inside the rAF callback, not in the stale event closure
UI freeze on large mailboxes (17k+ emails) โ monolithic getEmailHeaders() reading all 17k sidecar JSON files replaced with getEmailHeadersPartial(200) for instant display; added load_email_cache_meta Rust command for metadata-only reads; heavy Rust commands (save_email_cache, load_email_cache_partial, maildir_list, maildir_read_light_batch) moved to tokio::spawn_blocking to prevent main-thread blocking
Endless spinner on account switching โ getLocalEmails() reading all .eml files removed from setActiveAccount, setActiveMailbox, and loadEmails hot paths; archived emails now load via fire-and-forget getArchivedEmails() (reads only archived .eml subset); added _loadEmailsGeneration counter to cancel stale concurrent loadEmails calls on rapid account switching
Background pipeline re-reading 17k files โ EmailPipelineManager now uses in-memory pipeline._lastLoadedEmails from Phase 1 header loading instead of calling db.getEmailHeaders() for Phase 2 content caching
Whole-store Zustand subscriptions โ added useShallow selectors to ChatBubbleView, ChatSenderList, ChatViewWrapper, EmailViewer; converted bare useMailStore() to individual selectors in useEmailScheduler and SearchBar
v1.7.0February 21, 2026
Added
Email threading (Gmail-style) โ emails are now grouped into threads using RFC 2822 In-Reply-To and References headers, with normalized subject as fallback; the regular email list shows collapsed thread rows with participant names, message count badges, and latest date; the chat view uses the same threading algorithm for its topic grouping; Rust IMAP layer now fetches In-Reply-To from ENVELOPE and References via BODY.PEEK[HEADER.FIELDS (References)]
Thread conversation view โ clicking a thread in the email list now shows all emails in the thread as a stacked conversation in the viewer; emails are sorted chronologically with the latest expanded by default; each email has its own reply/reply-all/forward buttons and attachment section; email bodies load progressively using the same concurrent loader as the chat view
Chat view: sent message merge โ chat conversations now display both received (INBOX) and sent messages together; Sent folder headers are synced via the background pipeline and merged with INBOX emails, with deduplication by Message-ID to avoid duplicates; body loading handles per-mailbox IMAP fetches transparently
Clear cache button โ Settings > Storage now has a "Clear Cache" button that removes all cached .eml files and headers, preserves archived emails, and restarts the sync pipeline
Hide/unhide accounts โ accounts can be hidden from Settings > Accounts; hidden accounts disappear from the sidebar and stop all syncing (background pipelines, scheduled refresh); unhiding immediately resumes sync; if the active account is hidden, the app switches to the next visible account
Removed
App Password fallback for OAuth2 providers โ Gmail and Microsoft accounts no longer show the "Use App Password instead" toggle; OAuth2 is the only authentication method for these providers as app passwords are less secure
Fixed
Thread row actions โ threaded email rows in the list view now show archive and more-menu buttons on hover (matching single-email rows); archive button archives all emails in the thread; more menu offers "Delete thread from server" with confirmation
Chat view "Content cannot be displayed" โ chat bubbles showed "Content cannot be displayed" for all messages because the chat view only received header-only emails (no body content); added progressive body loading via useChatBodyLoader hook that fetches email bodies concurrently (3 at a time) from cache โ Maildir โ IMAP, with per-bubble loading spinners and targeted re-renders
v1.6.0February 20, 2026
Added
Gmail OAuth2 sign-in โ Gmail accounts now support "Sign in with Google" via OAuth2 PKCE flow, alongside the existing Microsoft OAuth2; uses Thunderbird's public Google client ID with https://mail.google.com/ scope for IMAP and SMTP access
Multi-provider OAuth2 architecture โ OAuth2 backend refactored from Microsoft-only to a provider-agnostic design; adding new OAuth2 providers requires only a new ProviderConfig entry in Rust
Automatic OAuth2 token refresh โ access tokens are now refreshed proactively 5 minutes before expiry; refresh is deduplicated across concurrent calls, persisted to Keychain, and patched into the live store so all pipelines and UI operations get fresh tokens transparently
Collapsible sidebar โ click the panel icon in the sidebar header to collapse it to a narrow icon-only strip (~56px); expands back with one click; state persisted across sessions
Compact email list view โ alternative 2-line layout (sender + date on line 1, subject on line 2) selectable from Settings > Appearance
Account avatar initials & colors โ account avatars now show the first letter of the display name (or email) on a deterministic color circle instead of a generic person icon; each account gets a unique color, customizable per-account from Settings > Accounts
From account selector โ compose modal shows a "From" dropdown when multiple accounts exist, defaulting to the currently active account
Per-account mailbox memory โ switching accounts restores the last selected folder for that account instead of always resetting to INBOX
Non-selectable folder handling โ IMAP \Noselect folders (e.g. Gmail's [Google Mail]) now expand children on click instead of triggering a SELECT error
Fixed
Inline images treated as attachments โ embedded images with Content-ID (referenced via cid: in HTML) incorrectly showed the paperclip icon in the email list and appeared in the attachment section; BODYSTRUCTURE walker now checks Content-ID to distinguish embedded images from real attachments, and .eml parsing applies the same filter (tracking pixels also excluded)
Gmail XOAUTH2 auth hanging โ async-imap's authenticate() deadlocked because the IMAP server greeting was not consumed before starting the SASL handshake; added explicit read_response() to drain the greeting first
XOAUTH2 authenticator infinite loop โ when the server rejected XOAUTH2 with a + error challenge, the authenticator resent the full token on every challenge; now sends empty response on subsequent challenges to let the server close cleanly
Gmail OAuth2 "client_secret is missing" โ Google requires client_secret even for PKCE public clients (unlike Microsoft); added Thunderbird's public Google client secret as default
OAuth2 sign-in endless spinner โ entering wrong credentials during OAuth2 sign-in left the UI in a permanent loading state; added Cancel button to abort the OAuth2 flow
Test connection timeout โ imap_test_connection had no timeout; wrapped in 20-second tokio::time::timeout
OAuth2 token refresh race condition โ concurrent callers could bypass the deduplication guard; moved guard registration before any async operation
Missing token refresh at IMAP entry points โ markEmailReadStatus, performSearch, and setActiveAccount didn't call ensureFreshToken, causing expired-token failures for OAuth2 accounts
Server-side search broken for OAuth2 โ performSearch only checked account.password; now uses hasValidCredentials() which accepts both password and OAuth2 tokens
Mailbox folders unsorted โ folders appeared in arbitrary server order; now sorted alphabetically with INBOX pinned first
"Invalid from address" on send โ special characters in display name broke format!() address parsing; now uses lettre::Mailbox::new() for proper RFC 5322 formatting
Namespace error on account switch โ old mailbox path (e.g. [Google Mail]/Spam) carried across accounts; fixed with per-account mailbox memory
Cloud icon doubling on Retina โ CSS opacity-50 on Lucide SVG caused double-compositing; replaced with rgba() inline color
Badge count log spam โ set_badge_count logged on every call; added deduplication and downgraded to debug level
v1.5.0February 19, 2026
Performance
Delta-sync on folder/account switch โ switching mailbox or account now checks IMAP UIDVALIDITY + UIDNEXT before fetching; if nothing changed, the cached email list is kept as-is with zero IMAP fetches; when emails were added or deleted, only the diff is fetched via UID SEARCH ALL + UID FETCH for new UIDs, instead of re-downloading the entire first page
Lazy email parsing โ opening an email now only parses text/HTML body and attachment metadata; attachment binaries and raw source are no longer loaded upfront, reducing parse time from ~60ms to ~8ms for a 5 MB email
On-demand attachment loading โ attachment content is fetched from the .eml file only when the user clicks download, eliminating wasted memory for unviewed attachments
On-demand raw source โ "View Source" now loads the full email source lazily instead of including it with every email open
Optimized email list rendering โ EmailRow wrapped in React.memo with stable selectors, eliminating thousands of unnecessary re-renders per store mutation at scale (10k+ emails)
Light IMAP fetch โ new imap_get_email_light command returns only body text and attachment metadata from the server, auto-persisting the full .eml to Maildir for later on-demand access
Light Maildir reads โ getLocalEmails() and email selection now use maildir_read_light which skips base64-encoding attachment binaries and raw source
Light background caching โ content caching pipeline now uses fetchEmailLight (Rust auto-persists .eml) instead of fetching full email + JS-side save, reducing memory and bandwidth per cached email
Fixed
Garbled sender/subject in email list โ non-ASCII names and subjects (e.g. =?windows-1257?Q?Ona_...?=) appeared as raw RFC 2047 encoded text in the email list; IMAP envelope values are now decoded through mailparse before display
Attachment indicators missing from email list โ IMAP header fetches never detected attachments because BODYSTRUCTURE wasn't requested; now included in the FETCH command so hasAttachments is set correctly at the header level without needing to open the email
Attachment section not showing in email viewer โ hasAttachments updates only wrote to the emails array but not to emailsByIndex (the Map used by the virtual-scroll list); now both are updated in sync when selecting an email or background-caching completes
IMAP namespace error โ servers requiring mailbox prefix (e.g., INBOX.Sent instead of Sent) would fail with "nonexistent namespace" when the app fell back to hardcoded mailbox paths; now caches server-returned mailbox paths and falls back to INBOX-only when no cache exists
Black screen crash โ app going to a black screen after extended use due to WKWebView memory exhaustion; stripped heavy fields (rawSource, attachment content) from in-memory cache, reduced default cache limit from 5GB to 512MB, and eliminated wasteful Map copies on every cache read/write
Iframe event listeners (click, contextmenu) leaked on every email selection โ now properly cleaned up when switching emails
Rust panic hook installed โ panics are now logged to stderr/system log before process abort, aiding crash diagnosis
Update checker blocked a Tokio worker thread with std::thread::sleep โ replaced with async tokio::time::sleep
Email archive from cache could fail when rawSource was not available โ now falls through to a fresh IMAP fetch
Bulk archive ("Archive Selected") now correctly sets the archived flag โ previously only set seen, so bulk-archived emails didn't appear in Local view
Failproof email loading โ emails that fail to load are now retried with unlimited exponential backoff (3s โ 9s โ 18s โ 36sโฆ capped at 120s) instead of being silently skipped
OAuth2 accounts (Microsoft 365) silently failed to load email content โ background caching and header loading both checked only for password, now correctly accept OAuth2 access tokens
All network activity pauses automatically when app goes offline and resumes on reconnect (both header loading and content caching pipelines)
Per-message error handling on the server โ one malformed email no longer kills the entire page fetch; failed messages are skipped with a warning and the rest load normally
IMAP connection retry now covers more transient error types (BYE, closed, SERVERBUG, EPIPE, EAI_AGAIN) in addition to timeouts and resets
Priority IMAP connections (used for single email fetch) now properly cleaned up on error/close, preventing stale connection buildup
Guard against stale state updates when user switches mailbox while background loading is in progress
Mailbox mutation detection โ if another client adds or deletes emails mid-pagination, sequence numbers shift and MailVault now detects the total change and restarts pagination instead of loading duplicates or gaps
Stale UID cleanup on refresh โ cached emails deleted on another client are removed from the local list when the server no longer returns them in the overlap window
Server returns skipped UIDs to client for retry instead of silently dropping them; client re-requests the affected page/range after 5 seconds
Server graceful shutdown now cleans up both priority and background IMAP connection pools (previously leaked priority connections)
Drag-and-drop account reordering in sidebar and settings had no visible effect โ components weren't subscribed to the accountOrder state, so reorders were persisted but never reflected in the UI
Added
Native Rust IMAP/SMTP โ replaced Node.js sidecar server with native async-imap and lettre crates; all email operations now run directly in the Tauri process via invoke() commands (no more HTTP to localhost:3001)
IMAP connection pooling โ two-pool design (background + priority) with NOOP health checks and automatic reconnection on stale sessions
Native OAuth2 PKCE flow โ Microsoft OAuth2 moved from Node.js to Rust with PKCE code challenge, local TCP callback server on port 19876, and automatic token refresh
UID EXPUNGE support โ permanent email deletion now uses RFC 4315 UID EXPUNGE to only remove the targeted message, not all deleted messages in the mailbox
Background loading pipeline architecture โ dedicated AccountPipeline class manages per-account header loading and content caching with configurable concurrency
Multi-account background sync โ after the active account finishes loading, all other accounts' INBOX headers are fetched and cached automatically
Parallel content caching โ active account downloads 3 email bodies concurrently (up from 1); background accounts use 1 concurrent worker
Cross-account cascade โ after active account content is fully cached, background accounts also get their email bodies cached sequentially
Shared credential helper (authUtils.js) โ single source of truth for password/OAuth2 credential validation
Bulk archive runs on Rust async thread pool โ 3 concurrent email fetches via IMAP pool, with progress events and cancellation support; no longer blocks the JS event loop
Removed Node.js sidecar server โ no more bundled binary, sidecar spawning, health check polling, or HTTP-based API calls; reduces app size and startup time
v1.4.11February 19, 2026
Fixed
Sidecar server port conflict after app update โ old sidecar process stayed alive on port 3001, blocking new instance; new sidecar now sends a shutdown request (POST /api/shutdown) to the old instance before retrying, enabling graceful handoff without shell commands (blocked in sandbox)
v1.4.10February 19, 2026
Fixed
API calls now routed through Tauri HTTP plugin instead of WKWebView's native fetch โ App Sandbox blocks WebView from making HTTP requests to localhost sidecar; the plugin routes requests through Rust's networking stack, bypassing the restriction
Fixed duplicate http:default capability identifier that could cause permission conflicts
Added
Comprehensive diagnostic logging throughout the connection flow: API module startup, HTTP plugin loading, health check polling, request lifecycle, and IMAP test-connection steps โ enables pinpointing exactly where failures occur in sandbox environments
v1.4.9February 19, 2026
Fixed
"SecurityError: the operation is insecure" crash caused by Web Worker โ WKWebView blocks blob: URL workers under the tauri:// origin; replaced Web Worker with main-thread queue processor (no functionality lost, all I/O was already on the main thread)
Infinite spinner when adding an account โ sidecar server crashed silently on EADDRINUSE (port 3001 occupied by previous instance) and the frontend waited forever; sidecar now retries port binding up to 5 times before exiting cleanly so the crash is detected and reported
Frontend API requests now have a 30-second timeout (AbortController) to prevent infinite hangs
Health check polling now throws and resets on failure, allowing retry on subsequent API calls instead of caching the failed state forever
IMAP test-connection timeout reduced from 30s to 15s for faster settings detection feedback
v1.4.8February 19, 2026
Fixed
"SecurityError: The operation is insecure" crash โ completely replaced localStorage with Tauri filesystem-backed storage; WKWebView in App Sandbox blocks all web storage APIs, now settings persist via JSON file on disk instead
Black screen on first launch โ Framer Motion animations starting at opacity 0 could stay invisible if animation engine failed in WKWebView
Added React error boundary with visible fallback UI and stack trace for rendering crashes
Splash screen now only dismisses after React successfully renders (not before)
Added 10-second timeout fallback if app fails to load โ shows reload button instead of blank screen
Added
Blog section on website with post about the v1.4.x signing saga
Changed
Updated README icon descriptions to match current UI
v1.4.5February 18, 2026
Fixed
Sidecar crashing in sandboxed release builds โ sidecar now signed with dedicated entitlements (no sandbox, JIT allowed) while main app keeps App Sandbox; signing order corrected (sidecar first, no --deep)
v1.4.4February 18, 2026
Fixed
Sidecar server crashing on launch in release builds โ App Sandbox blocked Bun's JIT compiler; sidecar now signed with dedicated entitlements (no sandbox, JIT allowed)
Removed --deep codesigning flag that was overwriting sidecar entitlements
Replaced shell-based process cleanup (lsof, kill) with Tauri CommandChild handle
v1.4.3February 18, 2026
Fixed
Sidecar server not starting in sandboxed builds โ removed shell commands (lsof, kill) blocked by App Sandbox, replaced with Tauri CommandChild handle for clean process management
v1.4.2February 18, 2026
Fixed
Sidecar server unable to start in sandboxed release builds โ added missing network.server entitlement so the backend can listen on localhost
v1.4.1February 18, 2026
Fixed
"Server unreachable (/test-connection): Load failed" when auto-detecting server settings โ raw fetch bypassed the API base URL in Tauri builds
v1.4.0February 18, 2026
Fixed
Server unreachable error in release builds โ sidecar now explicitly binds to 127.0.0.1 to prevent IPv4/IPv6 mismatch
v1.3.0February 18, 2026
Added
Settings menu item in macOS app menu (Cmd+,) for quick access to Settings
Escape key closes Settings page
Copy button in logs section โ copies logs to clipboard with "Copied!" feedback
Microsoft 365 OAuth2 (XOAUTH2) support โ sign in with Microsoft for Outlook/Hotmail/Live/M365 accounts
"Sign in with Microsoft" button in account setup for Outlook provider (uses PKCE authorization code flow)
OAuth2 token auto-refresh โ access tokens refresh automatically when expired
OAuth2 account status in Settings โ shows "Connected" / "Token expired" badges, with Reconnect button
OAuth2 callback server on localhost:19876 โ temporary server for receiving Microsoft auth redirects
server/oauth2Config.js โ Microsoft OAuth2 endpoints and credential configuration
updateOAuth2Tokens() helper in db.js for updating tokens after refresh
OAuth2 API functions in api.js โ getOAuth2AuthUrl, exchangeOAuth2Code, refreshOAuth2Token
App Password fallback โ users can still choose password auth for Outlook accounts
Fixed
Settings page blank screen โ missing AnimatePresence import from framer-motion
Notifications now show app icon โ replaced AppleScript osascript with tauri-plugin-notification
Email content now renders with original formatting preserved โ removed aggressive dark mode CSS overrides that broke email layouts, centering, and styled elements; emails now display on a light background (like Apple Mail) regardless of app theme
IPv6 connection hangs with Outlook โ forced IPv4 on all IMAP/SMTP connections
Multiple sidecar server processes โ added orphan cleanup on startup and kill on quit
Changed
IMAP/SMTP auth now supports accessToken (XOAUTH2) in addition to password auth
Outlook provider renamed to "Outlook / Microsoft 365" with OAuth2 as recommended auth method
Account setup for Outlook defaults to OAuth2, with "Use App Password instead" fallback link
Settings Authentication section shows auth type badge (Password vs Microsoft OAuth2)
OAuth2 now uses Mozilla Thunderbird's public client ID by default (no Azure app registration needed)
Specific error message for Microsoft Outlook IMAP regression with link to FAQ
"Sign in with Microsoft" button requires email before clicking and uses purple accent styling
v1.1.0February 16, 2026
Changed
Emails now stored as standard .eml files (RFC 5322) in Maildir format
Opening an email automatically caches it locally (download once, read forever)
"Save locally" now archives emails with a Maildir flag
Local view shows only explicitly archived emails
Email file operations moved to Rust for better performance
Extracted keychain parsing utilities to src/services/keychainUtils.js for testability
Backup format changed from JSON blob to ZIP archive of .eml files for better performance and portability
ZIP structure uses email addresses (not UUIDs) so backups are portable across installations
Export/import now uses Rust for file operations (faster, handles large mailboxes)
Export dialog lets you choose between "All Emails" or "Archived Only"
Import automatically creates new accounts for unrecognized email addresses (user re-enters password in Settings)
Raw email source always available for cached emails
Automatic migration of existing saved emails to .eml format
Unit tests for legacy keychain migration (parseKeychainValue, getAccountsFromKeychain, cleanup logic)
GitHub Actions CI workflow โ runs tests on push/PR to main
"Open in New Window" โ pop-out button in toolbar + custom right-click menu in email iframes, uses WebviewWindowBuilder to open a native Tauri window
Email popup windows close normally (only main window hides to tray)
export_backup and import_backup Tauri commands (Rust) for ZIP-based backup
src/services/backupUtils.js with testable pure utility functions
Unit tests for backup utilities (buildBackupEmailPath, matchAccountsByEmail, parseBackupManifest)
Extracted computeDisplayEmails utility (src/services/emailListUtils.js) for testability
Unit tests for display email computation โ covers all view modes, local-only flag logic, edge cases (18 tests)
Unit tests for state transitions โ archiveโdeleteโlocal-only flow, cache restoration, quick-load state (13 tests)
Integration test for local-only flag detection โ real IMAP flow: send โ archive โ delete from server โ verify flag (4 tests)
CI workflow now writes .env.test from GitHub secrets for integration tests
initBasic() in db.js โ lightweight init that skips keychain, used by quick-load
Removed
Session Cache settings from Settings page โ redundant now that Maildir auto-caches every opened email to disk; in-memory cache still works silently with default limit
Fixed
Dark mode email text readability โ force light text via inline !important on all elements (EmailViewer + ChatBubbleView)
Logs no longer clear before confirmation โ replaced confirm() with Tauri dialog ask() for proper async blocking
Dynamic version display from package.json
Export/import backup compatibility with new storage format
Backup export now works in Tauri WebView (replaced broken blob download with native save dialog + Rust ZIP writer)
Backup import now correctly restores all emails (previously silently skipped every email due to missing accountId/mailbox fields)
"Open in New Window" now works on macOS โ popup loads HTML from a temp file instead of eval on about:blank (WKWebView ignores eval before page ready)
Email list no longer shows empty placeholder cells when scrolling โ virtual scroll row count now matches loaded emails instead of server-reported total
Email list no longer shows overlapping rows after switching accounts โ email state fully cleared on account switch + virtual scroll container keyed by account ID
Email list no longer shows overlapping rows after switching view modes โ scroll position resets on view mode change + virtual scroll container keyed by view mode
Delete confirmation no longer hides the email content view โ replaced native confirm() dialogs with inline React modals in EmailViewer and EmailRow
"Local only (deleted from server)" indicator now clearly visible โ changed from tiny corner dot to amber-colored HardDrive icon; fixed local view mode to check server UIDs
After deleting from server, email immediately shows as local-only โ emails array updated synchronously before background refresh; cached headers on disk also updated to prevent loadEmails from restoring the deleted email
Local-only flag now only appears for explicitly archived emails, not auto-cached ones
Local view mode now correctly filters to show only archived emails (not all cached emails)
No more black screen on app launch โ quick-load uses initBasic() which skips keychain; shows cached emails + branded loading while keychain password prompt is active