Email… One of the last bastions of non-proprietary communication with the freedom to choose both service providers and clients alike. Some call it archaic but none can avoid using it to some degree. For years I struggled to find an email client I actually liked. I tried all the usual suspects: Mozilla Thunderbird, mutt, alpine, and others. Even mu4e didn't scratch that itch.
I've spent the last few years on Thunderbird as I made a point that even if everything else is failing, email must work, so I tried to avoid any unnecessary hackery. In the end my nature got better of me: about one year ago I switched to Notmuch and now I think I'm ready to write down my experience.
Notmuch is at its core an email search engine. It indexes the mails and allows to query the resulting database. That's all it does, there is no fetching and sending email or the UI apart from the CLI tool. For these things I needed separate tools.
I chose isync to fetch my email and msmtp to send it. At first glance it seems more complex than simply clicking away the settings in Thunderbird but I actually like it better. They are configured with plaintext and there is a very clear separation of concerns. The config files look like this:
defaults port 587 tls on tls_trust_file /etc/ssl/certs/ca-certificates.crt account HomeAccount host smtp.example.com from firstname.lastname@example.org auth on user email@example.com passwordeval pass firstname.lastname@example.org account WorkAccount host mail.workplace.example.com port 465 from email@example.com auth on tls_starttls off user firstname.lastname@example.org passwordeval pass email@example.com account Gmail host smtp.gmail.com from firstname.lastname@example.org auth on user email@example.com passwordeval pass firstname.lastname@example.org account default : HomeAccount
IMAPAccount HomeAccount Host imap.example.com User email@example.com PassCmd "pass firstname.lastname@example.org" SSLType IMAPS IMAPStore HomeAccount-remote Account HomeAccount MaildirStore HomeAccount-local Subfolders Verbatim Path ~/Mailemail@example.com/ Inbox ~/Mailfirstname.lastname@example.org/Inbox Channel HomeAccount Master :HomeAccount-remote: Slave :HomeAccount-local: Patterns * Create Both Expunge Both SyncState * IMAPAccount WorkAccount Host mail.workplace.example.com User email@example.com PassCmd "pass firstname.lastname@example.org" SSLType IMAPS IMAPStore WorkAccount-remote Account WorkAccount MaildirStore WorkAccount-local Subfolders Verbatim Path ~/Mailemail@example.com/ Inbox ~/Mailfirstname.lastname@example.org/Inbox Channel WorkAccount Master :WorkAccount-remote: Slave :WorkAccount-local: Patterns * Create Both Expunge Both SyncState * IMAPAccount Gmail Host imap.gmail.com User email@example.com PassCmd "pass firstname.lastname@example.org" SSLType IMAPS IMAPStore gmail-remote Account Gmail MaildirStore gmail-local Subfolders Verbatim Path ~/Mailemail@example.com/ Inbox ~/Mailfirstname.lastname@example.org/Inbox Channel Gmail Master :gmail-remote: Slave :gmail-local: Patterns * Create Both Expunge Both SyncState *
If you don't like the syntax (it's not great but it does its job), don't worry, there is little need to touch these files after the initial setup, unless you need to add or remove an account.
In both cases, I'm using pass(1) for the password storage instead of putting my passwords in plaintext there. I find pass excellent for automated access like this.
Summarizing: After fetching my inbox using isync, I have a full
offline copy of all my mails at
OK, we're done with the internals. As for the UI, I chose notmuch.el. It's based on GNU Emacs, so it's right up my alley. There are other alternatives, including using Notmuch from mutt/neomutt or dedicated frontends like alot.
If you're using Notmuch as a search engine for a "regular" email client like mutt, that's about it. But I was going to use a client centered around Notmuch so the fun only begins. First of all, since it's essentially a database, Notmuch has no concept of folders. Instead it makes extensive use of tags, similar to the ones known from Gmail but with a few very important differences. I didn't like the Gmail tags because they wanted to be both tags and folders simultaneously. What do I mean? You needed to create them (one way or another) and they still existed even when empty. For me it felt like a pretty big cognitive overhead to create a new tag as it would linger for probably too long and pollute the namespace. In Notmuch the tag exists only as long as there are messages with this tag. The tags are inherently bound to messages and don't exist as a separate concept. These are the main tags I use:
inbox(for non-archived mail, archiving consists on only removing this tag),
new(for the mail that appeared in the latest fetch and weren't there before),
- many less interesting ones.
Some of them are directly tied to the server-side flags (like
flagged), others exist solely in the Notmuch index and I assign
them using the pre- and post-hooks that are being run before and after
I refresh the mail index respectively. For instance, my pre-hook
#!/bin/bash -e notmuch tag -new -- tag:new mbsync -a || true
…so first I remove all the
new tags from the previous run and then
Notmuch runs mbsync for me to fetch all the new mail. I assign
new tags by specifying this option in
My post-hook is much more personalized, so there's little point in posting it whole here, but that's the place where one would add various automated tagging rules. I have there rules like this, that make my work more organized:
notmuch tag +flagged -- tag:new and query:work and '"Assignee: Wojciech Siewierski"'
In notmuch.el tagging is done by pressing
+sometag to add some tag
-sometag to remove it. Yes, just a plus or minus and the tag.
It can be "chained" before confirming with Enter like this:
-unread +actionable -flagged. It feels really natural and doesn't
get in the way.
Considering Notmuch.el runs inside GNU Emacs, it allows to use all
its text processing capabilities when composing mail. It really makes
a difference for the Emacs power users and that alone is a major
argument for using Notmuch for me. It utilizes the Emacs
message-mode with some additions so most generic info about
composing email in Emacs found online applies here. GPG signing,
composing complex mail (like composing HTML mail with Markdown) or
attaching files is pretty easy thanks to that. For instance it's
possible to use
gnus-dired-mode created for the Gnus mail client
(also Emacs-based) to select the attachments directly with the dired
file manager (yes, you guessed), it doesn't even need to know anything
about Notmuch, it just knows about
message-mode. What really
message-mode handles a regular drag'n'drop of the
attachments from traditional graphical file managers, so if you're
leaning that way, more power to you!
I really came to like the way notmuch.el handles the HTML email. By default it prefers showing the plaintext version of email but if none is available or the user requests the HTML version it manually, it half-renders it. It's good enough to handle the links and formatting but usually not complete enough to allow all the usual crap HTML mail are infamous for in some communities. But if I do need to render it fully, notmuch.el can save the HTML part of the mail in a temporary directory and open it with a web browser. At first it felt inconvenient but I came to prefer it to the regular approach: I'll probably need to open a web browser to open some links in this mail either way, so I get a head start here.
When it comes to the regular email UI elements, notmuch.el is more than competent. It can display the mail list both as threads (one thread == one list element) and as trees (one thread == one tree, one mail == one tree node) and the thread navigation is top tier.
Is Notmuch + notmuch.el perfect? Of course not. My main
"complaint" is the disconnect between the abstract tags system and the
actual mailbox structure. I can include the mail folder hierarchy in
a Notmuch search query but that's it. When I want to know the
actual way my mail are stored, I either inspect the
notmuch tag -inbox -- tag:inbox and not folder:/Inbox/ and path:/@gmail.com/
…and I don't bother making Gmail aware of mail being archived in Notmuch.
Many will miss the lack of automatic mail checking out of the box but for me it's an improvement. I prefer to check my mail on my own schedule, not run to check it just because a notification came.
That's roughly how I've been using Notmuch for the last year. All in all, it's a trade-off I'm willing to accept but it's not for everyone. I don't see myself switching mail clients anytime soon. Notmuch is the best way I found to organize and search my mail, and it allows me to utilize my editor of choice. Even if you're not a fan of Emacs, it's worth a try with one of the other frontends, I know some happy users that did.