Bring the refined, modern layout of Apple Mail to MailMate — without sacrificing its power.
An Apple Mail-inspired interface for MailMate that keeps MailMate's native Smart Mailboxes, rules, IMAP, threading, search, Markdown, and keyboard-driven workflow.
| Before (Native MailMate) | After (Cupertino for MailMate) |
|---|---|
![]() |
![]() |
The name Cupertino refers to the home of Apple and signals the project's design inspiration. It does not imply affiliation with Apple.
Cupertino for MailMate does not patch MailMate.app. It uses MailMate's
user-level resource overrides and a companion theme. The installer generates
the overrides from the user's installed copy of MailMate and creates automatic
backups before replacing existing files.
Built and tested with MailMate 2.0 r6272 on macOS. Other MailMate builds may use different internal resource formats and are not yet verified.
- Reworks Standard Single Column into a compact four-line row: sender and date, subject, and two lines of message text.
- Replaces the expanded message header with three compact lines: sender/date, subject, and recipients. Details expands the remaining headers and then changes to Hide.
- Sorts threads by the latest
Date Received, newest first. - Keeps unread, reply, security, attachment, flag, and native thread behavior.
- Adds a minimal
Ncolumn so the table header remains available. - Applies
Apple Mail Single Column + Nto mailboxes and Smart Mailboxes. - Installs and enables the bundled PureVim keyboard navigation profile.
- Includes the optional Apple Mail Compact message-body theme.
- macOS
- MailMate 2.0 r6272
- Python 3
Quit MailMate, open Terminal in this project directory, and run:
zsh scripts/install.sh --verboseThe installer automatically backs up replaced files under:
~/Library/Application Support/MailMate/Backups/apple-ui-YYYYMMDD-HHMMSS/
It then installs the Apple-style message list, compact message header,
companion theme, saved mailbox layout, sorting state, and preview background
agent. It also enables the bundled PureVim custom key bindings. Pass
--skip-pure-vim to leave the user's key binding file and preference unchanged.
Restart MailMate after installation finishes.
Running the installer again upgrades the existing installation and creates a new backup. An existing complete preview cache is reused instead of rebuilt.
MailMate does not expose message body text directly to its native message-list
formatter. Cupertino for MailMate therefore builds a local custom header cache
from MailMate's downloaded .eml files.
For each message, the extractor normally reads the first 2 KiB of body data, decodes MIME and HTML content, removes common quoted-reply blocks, and keeps up to 180 characters. The result is split across the two preview lines. Messages and attachments are not modified, and no content is sent over the network.
A fresh installation processes at most the 2,000 most recent local messages. This keeps installation time predictable even when a mailbox contains tens of thousands of messages. Older messages are filled progressively by the background agent after installation.
The installer enables a macOS LaunchAgent automatically. The agent can be triggered in two ways:
- New mail trigger: the agent watches MailMate's local Date Received index
and message store. After MailMate writes new mail, the agent waits briefly
for the
.emlfile to settle and refreshes the 500 most recent messages. - 15-minute fallback: every 15 minutes, the agent checks for changed local messages and adds up to 2,000 uncached older messages. This continues until the local cache is complete.
When the cache is complete and no message has changed, the agent exits without
rewriting the JSONL or MailMate header caches. Messages whose bodies have not
yet been downloaded cannot show a preview until MailMate stores their local
.eml content.
MailMate memory-maps header caches and does not expose a verified extension API for reloading them while it is running. The agent updates the on-disk cache for new mail, but a newly generated preview can require restarting MailMate before it appears in the message list. Cupertino for MailMate does not automate that restart or request Accessibility/Automation permission.
The working preview index is stored at:
~/Library/Caches/MailMateApplePreview/mailmate-body-previews.jsonl
MailMate reads the generated header caches from:
~/Library/Application Support/MailMate/Database.noindex/Headers/x-apple-mail-preview*
The LaunchAgent is installed at:
~/Library/LaunchAgents/io.github.cupertinoformailmate.preview-refresh.plist
PureVim preserves MailMate's native commands while adding concise navigation bindings for a smoother keyboard-driven workflow.
| Keys | Action |
|---|---|
gg / G |
First / last message row |
Ctrl-f / Ctrl-b |
Move eight threads forward / backward |
s / r |
Toggle flag / read state |
a / f |
Reply all / forward |
gi / gd / gt |
Go to Inbox / Drafts / Sent |
ga / gs |
Go to All Messages / Flagged |
gc / ge |
Collapse / expand the selected thread |
The background agent updates the on-disk preview cache after MailMate stores
the local .eml file. MailMate r6272 memory-maps that cache and has no public
reload command, so the new preview can remain invisible until MailMate is
fully quit and reopened. This refresh delay is a MailMate limitation, not a
failed Cupertino for MailMate extraction.
Do not reinstall repeatedly over an unverified MailMate build. Quit MailMate, restore the latest automatic backup, and confirm that the native interface opens before reporting the new MailMate build:
zsh scripts/restore-last-backup.sh --verboseInclude the MailMate build number, macOS version, installer output, and a sanitized screenshot in the issue report.
Keep MailMate closed and run the same restore command above. Restore only
restores files saved before installation, removes resource paths that the
installer added, and disables Cupertino for MailMate's preview agent. It
does not touch mail data, account settings, or Mailboxes.plist.
Quit MailMate and restore the latest automatic backup:
zsh scripts/restore-last-backup.sh --verboseRestore returns installer-managed resource paths to their pre-install state and
disables Cupertino's preview agent. It does not modify messages, accounts, or
Mailboxes.plist.
Cupertino for MailMate uses verified r6272 resource extension points. MailMate does not currently expose verified hooks for an Apple Mail-style collapsible attachment bar, hover-only native attachment controls, or PDF behavior based on page count. It also does not expose resource settings for the composer attachment viewport height or a maximum-height scrolling attachment pane in received messages. Those features are intentionally not simulated here.
This is an independent community project and is not affiliated with Apple or MailMate. Apple Mail is a trademark of Apple Inc.
Warning
Version compatibility: this release is verified only with MailMate 2.0
r6272. It depends on user-level resource formats and local header-cache
structures which MailMate does not expose as a stable public API. If a
MailMate update breaks the layout or prevents startup, quit MailMate and run
zsh scripts/restore-last-backup.sh --verbose before trying another install.
The installer never modifies MailMate.app, accounts, or messages.
The original code and theme in Cupertino for MailMate are available under the
MIT License. See LICENSE. MailMate and locally generated files derived from
MailMate resources remain subject to MailMate's own license and are not
relicensed by this project.


