What changed in each version — newest first.
MailCode is on the Mac App Store, and updates arrive the way every other App Store app's do — the App Store offers them, and installs them if you have automatic updates on. If something on this page does not match what you are seeing, MailCode → About MailCode tells you which build you have.
Opening a message no longer waits for the download running behind it. While MailCode fills its local copy of a mailbox it writes each batch of messages to disk in one go, and everything else — opening a mail, opening a folder — had to wait its turn behind that write. On a large mailbox the wait reached nine seconds and the message gave up with "the archive is still busy", which read as though the message itself were the problem. It was not: the work of opening it took under a millisecond once it started. MailCode now pauses between writes so anything you click is answered straight away.
A folder opens while the download is still running. Some mail servers allow only one connection at a time, and Outlook narrows to one when it decides a client is asking for too much. MailCode always meant to keep a connection free for you and hand the rest to the background download — but with only one to divide, the download took it, and a click waited for a whole batch of messages to finish arriving. The download now stands aside when there is nothing to spare and you are waiting, and carries on if you are not.
An attachment you have already opened opens instantly. Opening a message quietly fetches its attachments, so that the Open button means the file is already here. It did fetch them — and then threw them away, so every click fetched the same file again from the mail server. A 3.6 MB spreadsheet cost ten seconds each time, including going back to a message opened minutes earlier. The bytes are now kept, and Open uses them.
Opening a mail attached to a mail no longer gives up. An attached message had thirty seconds to arrive, where every other kind of attachment had two minutes. On a slow or busy connection that ran out, and the failure blamed the local archive for a wait that was really the mail server's. It now has the same two minutes as everything else.
A meeting is sent at the hour you set it. A meeting created from the New Meeting form went out three hours late in Turkey, and by however far its own clock runs ahead of Greenwich anywhere else. The form wrote the time as plain wall-clock text with nothing to say which clock it had been read from, and Exchange reads a time with no zone on it as UTC — so a 14:00 meeting invited everyone to 17:00, the organiser's own copy included. The time now carries its offset. Updating a meeting, dragging one to a new slot, a reminder invitation and the New Meeting form opened from a message were all already correct, which is what made this look like a server's doing rather than MailCode's.
Signing in no longer sends you to your browser. Adding a Microsoft or Google mailbox used to open your default browser, leave MailCode behind it, and rely on you finding your way back. It now happens in the system's own sign-in window, drawn over MailCode: the same page from Microsoft or Google, on the same Safari session, so a mailbox you are already signed in to on this Mac does not ask for the password again. Your password is still typed on the provider's page and MailCode still never sees it. On Windows the browser is still the right window, and nothing there changes.
A Google sign-in no longer ends on a security warning. Google hands a "Desktop app" client one way back into the app — a plain http address on your own computer — and Safari's "Use secure connections" setting interrupts that at the very last step with a red This Connection Is Not Secure panel. The sign-in had in fact worked; it simply did not look like it. Google's iOS client type comes back on an address of its own, which the sign-in window recognises and closes on, so no web page is loaded at any point. Settings → Sync now describes making one, and tells the two apart by the secret: an iOS client has none, so leaving that box empty is what chooses the new route. A client you already set up goes on working unchanged, and is still the route Windows uses.
Microsoft accounts settle in faster, and say less that is not true. A mailbox talks to the server over one connection at a time, and MailCode keeps a second one so that what you click never waits behind what it is doing in the background — but the wrong things were on it. Opening a folder, marking mail read, flagging, deleting, moving and filing a sent copy all queued behind the first-time archive crawl, while the twelve-thousand-header warm-up that runs when an account is added sat on the lane the clicks were on. Everything a click starts now goes on the responsive connection and the background work goes on the other. Three things that were merely alarming are gone with it: a newly added mailbox that Microsoft has not finished opening is described as not open yet rather than accused of having no IMAP access; a sign-in the server rejects no longer tells someone with no password to check their password; and a folder being copied locally shows its progress on the account it belongs to, instead of on whichever account you happened to be looking at.
Mail the server only asked us to wait for is no longer written off. When Microsoft holds a mailbox off — it does this readily on a new account — MailCode waits a minute and picks up on its own. The first-time archive crawl did not know that, and treated the refusal as the fetch having failed: it spent all nine of its attempts inside the first ten seconds of that minute, wrote the messages off as unfetchable, and reported itself finished. On one Sent folder that was 33 messages recorded as missing from a mailbox that was working perfectly well. Related, and quieter: the table mapping a folder to its name on the server was shared between accounts and only refilled for the folders each account has, so on a mailbox whose folder list would not load, MailCode asked it for a folder belonging to a different account entirely.
A saved file asks where it should go. Three saves wrote straight into your Downloads folder without asking — the report from Report a Problem when sending it fails, an attachment saved from the window that opens for a double-clicked .eml or .msg, and an attached message that is not a .eml. Each now opens the same save panel every other save in MailCode opens, so the file lands where you want it and the app can tell you where that was.
Translation works again. MailCode translates a message through Google's free translation endpoint, which is reached with an undocumented key. On 24 August the key MailCode had used since the feature shipped began refusing every request — the first one of an idle session, from a machine with nothing in front of it — and it has not answered since. Nothing about MailCode had changed: the same machine, in the same second, was answered normally on two other keys, so what was blocked was the key and not you. MailCode now keeps a list of them and moves on the moment one refuses, remembering for the rest of the session which one answered, so a long document pays for that discovery once rather than on every page. A translation that fails still leaves the pages already done alone. The failure used to be silent — the translation simply did not appear — so it now records a line when it happens.
Your local archive now stays on your own machine. MailCode keeps your mail in a database in its own process and reads it over an HTTP port that only its own window is meant to use — but that port was opened without naming an address, which on every platform means every address. It answered anything that could reach the computer: another device on the café Wi-Fi, a guest on the office network, whatever else is on the VPN. Nothing had to be guessed but a port number, and what answered was the whole archive — search, message bodies, attachments, and the routes that send mail. It now listens on the loopback address alone, so the port exists only inside your computer and a request arriving from anywhere else is refused before it is read. Nothing about how the app works changes, and no setting ever turned this on.
An Outlook or Hotmail mailbox now says what it is doing while it sits empty. Microsoft rate-limits IMAP per mailbox and refuses calls with a suggested backoff — and on a mailbox you have just added, where the folder list, the first page of mail and the push connection all want the one connection at once, that meant the first page timed out and the once-a-minute folder poll walked back into the same window every minute for the next five. The status bar said "sync error"; the log said "Command failed", which is the one phrase the IMAP library reports every refusal as. The server's own words are read now, so a rejected command says which command and why, a throttle is answered with a plain sentence and a rate-limited, retrying state rather than an error, and the window is remembered per mailbox so everything waits it out together instead of taking turns re-arming it. An expired sign-in hiding behind the same three words now reaches the authentication banner it always should have. Gmail, which does not throttle this way, is untouched.
A custom accent colour follows the theme. The colour you picked was written straight through, so one chosen in Light+ stayed near-black after switching to Dark+ and took the folder names, the unread markers and the selection with it — and a pale one picked in Dark+ disappeared into white in Light+. The hue you picked is kept, and its lightness is walked toward the readable side of whichever background you are on until it clears the contrast bar for text. An accent that already read stays exactly as it was. Both themes remember the same pick.
Whatever you opened last comes to the front, and clicking either one raises it. A composer is a window and every dialog sat beneath it, so Settings opened while a draft was up came out behind the draft — and clicking it did nothing, because the compose window was still the top layer. Minimizing the draft was the only way to reach the dialog. Now the two behave like windows: the newest is in front, a click raises either, including a click inside the quoted message where a reply is usually written, and a raised dialog gives up its backdrop so that click can land. Panels that Settings itself opens — the storage panel, What's New, Report a Problem — also put Settings back when they close, on the tab and at the scroll position you left, instead of dropping you into the mailbox.
.docx
or .xlsx opened on a plane failed with nothing to say why. They ship inside
the app now, beside pdf.js, and are still loaded only when an Office attachment is
actually opened.
Read mail in the language you actually read in. Translation used to mean
English, and only English. Now Settings → AI Assistant → Translate mail into
sets the language, and the Translate button, a passage you highlight and a previewed
attachment all follow it. The language a message is already in is still detected rather
than asked for. The strip above a translated message carries the same list, so one mail
can be turned into another language on the spot without going near Settings, and a
translated attachment you download is named for the language it is in — (EN),
(TR) — so two translations of one file no longer land on top of each other.
Translating a draft you are writing stays a separate choice, made in the
composer each time: reading someone's mail and writing back to them are opposite
directions.
Take a translation back out. A translated message keeps its translation, which is what makes opening it again cost nothing — but until now Show Original only hid it, and there was no way to say a mail was finished with. The Translation strip now carries a Remove button that puts the mail back and forgets the translation, a passage you translated by hand comes out from a right-click on it, and Settings clears every saved translation at once. Both buttons ask once before they act. The message itself is never modified, either way.
Replies go out as replies. Messages sent from MailCode carried no
In-Reply-To or References header. Inside Exchange nothing looked
wrong, because Outlook threads on its own index — but in Gmail or Apple Mail each reply
arrived looking like an unrelated message, and the copy filed in Sent Items came back with
no parent, so MailCode's own conversation view could not chain your replies either. Both
headers are now written on the way out, over Exchange and over SMTP, and they survive a
message that waits in the Outbox or goes out on a schedule. Replies sent before this
version carry nothing to recover; a forward still carries neither, deliberately, so it
stays a line of its own rather than becoming a reply to mail its recipients never saw.
A crash that leaves nothing behind is now written down. A tester's Windows app vanished mid-gesture and left no trace anywhere: nothing in the app's own log, nothing in Event Viewer. A fault below the app runs none of the app's code, so nothing inside it was left to record its own death. Two witnesses now outlive it — a crash dump written by a handler process, and a session marker that proves the last session never reached its exit and says to within a minute when it stopped. Together they tell a crash apart from a kill. Report a Problem carries that history, and a dump is offered there rather than taken: it is a copy of the app's memory and can hold message text, so nothing is attached until you press the button, and nothing is ever uploaded on its own.
Also: a message the reading pane could not measure — one whose own layout is pinned to the window — had its tail clipped with no scrollbar to reach it. Height is now read from the mail's content, and a frame that still cannot hold the message hands the scrollbar back rather than hiding text. Hovering a row in the list, or a marker on the conversation timeline, now draws the message it answers and the messages that answered it. And the AI panel keeps the selection it was opened on, instead of quietly switching to the whole draft.
The beta expiry is judged against the download host's clock rather than the machine's, so winding the system clock back no longer walks past it. Both checks fail open when you are offline.
The beta window was extended to 1 December 2026. The previous build was made nine days before its own expiry and would have refused to launch on 1 September — and because an expired build quits before it can check for an update, it could not have fixed itself. Update if you are on 1.10.19 or earlier.
Translate an attachment and keep the page it came on. A Word document, a
spreadsheet or a PDF opened in the preview can be translated as a document: the preview
redraws with its headings, tables and styles intact, each block of translated text sits
over the block it replaces, and the translated copy can be saved as a real
.docx, .xlsx or PDF beside the untouched original.
a: and b: now answer with the message that actually carries
the file or the words, rather than the whole conversation around it — and a:
answers in IMAP folders at all, which it previously did not.
An exported .eml now carries the message's own identity, so mail exported to
disk keeps its threading and its place in the duplicate check when it is indexed on
another computer.
PST import recovers what it had been quietly dropping: attached emails, which arrived as unopenable 8-byte rows; real sender and recipient addresses instead of Exchange directory names; the read state; RTF-only bodies; and distinct messages the duplicate check had been collapsing into one.
Something in a new build behaving worse than the last one? Help → Report a Problem inside the app attaches the technical details for you — or write, and a human will read it.