What it is
emacs-mailto makes macOS mailto: links open in Emacs, using whatever
mail-user-agent you already have configured — mu4e, notmuch, Gnus, Rmail,
or plain message-mode. Click a mailto: link in your browser, and Emacs
comes to the front with a compose buffer already addressed.
The project lives at sr.ht/~bounga/emacs-mailto, where you’ll find the source and the ticket tracker.
The problem it solves
The GNU Emacs NS port — as shipped by emacs-plus, emacs-mac, or the
official build — does not handle mailto: URLs.
When Emacs is already running, clicking a mailto: link activates Emacs but
the URL never arrives: macOS brings the app to the front and drops the URL
Apple-event before it ever reaches Emacs Lisp. So nothing happens — no
compose buffer — and there is no way to fix it from your config, because the
event never gets there in the first place.
That’s the whole frustration emacs-mailto exists to remove.
How it works
emacs-mailto sidesteps the dropped Apple-event with a tiny relay app
registered as your default mail application. On a mailto: click, it brings
Emacs to the front and hands the URL to emacsclient:
open -a Emacs
emacsclient -n -e "(run-at-time 0 nil (lambda () (browse-url-mail \"<url>\")))"
browse-url-mail parses the mailto: URL — recipient, subject, body — and
opens a compose buffer through your mail-user-agent. The run-at-time
wrapper lets emacsclient return immediately instead of blocking on an
interactive prompt, such as a From-address picker.
A few details make it painless in practice:
emacsclientis located automatically at runtime (Homebrew on Apple Silicon or Intel, MacPorts,~/.local/bin, or/usr/bin), so no path is hard-coded.- The app is built and ad-hoc signed locally by the installer, so there is no Gatekeeper quarantine and no pre-built binary to trust.
Requirements
- macOS
- Emacs running with a server (
M-x server-start, or the Doom/Spacemacs defaults), soemacsclientcan reach it - A configured
mail-user-agent— this is what actually opens the compose buffer
Installation
Clone the repository and run the installer:
git clone https://git.sr.ht/~bounga/emacs-mailto
cd emacs-mailto
./install.sh
This compiles Emacs Mailto.app into ~/Applications, registers it, and
sets it as the default mailto: handler.
Test it:
open "mailto:test@example.com?subject=Hi"
Emacs should come to the front with a compose buffer addressed to
test@example.com.
If your Emacs app has a different name, or you want a custom bundle identifier, override them with environment variables:
EMACS_APP="Emacs" BUNDLE_ID="org.nongnu.emacs-mailto" ./install.sh
A caveat about the default mail app
The relay runs as a background agent (LSUIElement), so it does not
show up in Mail → Settings → General → “Default email application”. That
menu may keep displaying another app — ignore it. To check the real handler,
ask LaunchServices directly:
swift -e 'import AppKit; print(NSWorkspace.shared.urlForApplication(toOpen: URL(string:"mailto:x@y.z")!)!.path)'
It should print .../Emacs Mailto.app.
Uninstall
./uninstall.sh
This removes the app and resets the mailto: handler to Apple Mail.
Wrapping up
That’s the whole tool — a small relay that removes a long-standing papercut of running Emacs as a mail client on macOS. It’s MIT licensed. If you hit a rough edge with your particular Emacs build or macOS version, the tracker is on the project page at sr.ht/~bounga/emacs-mailto.
Share on
Twitter Facebook LinkedInHave comments or want to discuss this topic?
Send an email to ~bounga/public-inbox@lists.sr.ht