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.
I’m not switching back, Notmuch is great.
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:
passwordeval pass email@example.com
passwordeval pass firstname.lastname@example.org
passwordeval pass email@example.com
account default : HomeAccount
PassCmd "pass firstname.lastname@example.org"
PassCmd "pass email@example.com"
PassCmd "pass firstname.lastname@example.org"
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
~/Mail. Notmuch can then index
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
new (for the mail that appeared in the latest fetch and weren’t
- 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
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
manually or just start Thunderbird which I’m still keeping as my
fallback (remember? Email must work!). Additionally, the way I use
email is very centralized. The Notmuch metadata is stored locally,
so using it on more than one device is tricky. I have a single
machine I run Notmuch on so I didn’t have a chance to try
muchsync but it’s definitely more work than just logging in via
IMAP and being done with it. I have a few rules to handle the Gmail
mail I archived on my mobile devices:
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
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.