My Strategy for Using the Terminal Email Clients

Dec 31st, 2025 @ bertyuan's web page

Although GitHub now occupies a large share of the market for code hosting services, many projects still prefer to use mailing list for communication and   patch submission.[1] In this post, I will outline my thoughts for using Aerc and NeoMutt configured with Mutt-Wizard.


Getting started

Please let me ramble on.
Aerc is available on most GNU/Linux distributions and macOS via Homebrew. (Sorry, no Windows here)
Check for official installation instructions of Aerc.
And the same for NeoMutt:
Check for official installation instructions of NeoMutt.

It is recommended to use Mutt-Wizard from Luke Smith to set up NeoMutt, which simplifies the configuration process significantly. But for those who prefer manual configuration, you can either set every component up, or use your own configuration files to override Mutt-Wizard's defaults.

My configurations

It is widely known that both Aerc and NeoMutt are customizable, especially NeoMutt.
Here I will list some of my configurations for reference.

Aerc

For Aerc, this is how the config file folder looks like:
> tree
.
├── accounts.conf
├── aerc.conf
├── binds.conf
└── stylesets # optional for custom stylesets
    └── foo

In accounts.conf, I add this line: copy-to-replied = true, to make threads in the same mailbox.
Or you can set threads by notmuch with its virtual folder feature. Then you do not need this config.
Therefore, I need to set up threads in aerc.conf as well:

threading-enabled=true

Also, I do not like the default setting of replying to self in Aerc, so I add this:

reply-to-self=false

In binds.conf, I set up some keybindings for convenience:

# make `d` to move to Trash
d = :read<Enter>:move Trash<Enter>

[messages:folder=Trash]
# d = :choose -o y 'Delete Forever' delete-message<Enter>
d = :prompt 'Delete Forever?' delete-message<Enter>

# mutt-like keybindings
l = :view
h = :close

The last one (optional) for Aerc is to set up a custom style in stylesets/foo:
Here's mine:

*.selected.bg = #1793D1 # arch blue
*.selected.fg = 15      # while or change to default
*.selected.bold = true
# Arch Linux blue borders
border.fg = #1793D1

And don't forget to source it in aerc.conf:

styleset-name=foo

NeoMutt

After setting up NeoMutt with Mutt-Wizard, I would like to make some changes to the default configuration, as the dafault ones are for Luke himself, not for me.
So I changed the colors first in ~/.config/mutt/muttrc:

# Default index colors:
color index white default '.*'
color index_author blue default '.*'
color index_number white default
color index_subject white default '.*'

color status color8 default
color sidebar_highlight blue default

Then the bindings:

bind index,pager \Cl list-reply
bind index,pager J sidebar-next # ======================================
bind index,pager K sidebar-prev # The same bingding as in Aerc,
bind index,pager L sidebar-open # while keeps the dafault ones from Mutt

Unfortunately, Mutt/NeoMutt does not support patch highlighting like Aerc does.
So I can only use this[2] to mannually highlight patches, though sometimes it would mistakely highlight non-patch emails:

# --------------
# Simple version
# --------------
# color body green default "^diff \-.*"
# color body green default "^index [a-f0-9].*"
# color body green default "^\-\-\- .*"
# color body green default "^[\+]{3} .*"
# color body cyan default "^[\+][^\+]+.*"
# color body red  default "^\-[^\-]+.*"
# color body brightblue default "^@@ .*"

# -------------------
# Conplicated version
# -------------------
#color   normal  white           default
color   body    brightwhite     default         ^[[:space:]].*
color   body    yellow          default         ^(diff).*
#color   body    white           default         ^[\-\-\-].*
#color   body    white           default         ^[\+\+\+].*
#color   body    green           default         ^[\+].*
#color   body    red             default         ^[\-].*
#color   body    brightblue      default         [@@].*
color   body    brightwhite     default         ^(\s).*
color   body    cyan            default         ^(Signed-off-by).*
color   body    cyan            default         ^(Docker-DCO-1.1-Signed-off-by).*
color   body    brightwhite     default         ^(Cc)
color   body    yellow          default         "^diff \-.*"
color   body    brightwhite     default         "^index [a-f0-9].*"
color   body    brightblue      default         "^---$"
color   body    white           default         "^\-\-\- .*"
color   body    white           default         "^[\+]{3} .*"
color   body    green           default         "^[\+][^\+]+.*"
color   body    red             default         "^\-[^\-]+.*"
color   body    brightblue      default         "^@@ .*"
color   body    green           default         "LGTM"
color   body    brightmagenta   default         "-- Commit Summary --"
color   body    brightmagenta   default         "-- File Changes --"
color   body    brightmagenta   default         "-- Patch Links --"
color   body    green           default         "^Merged #.*"
color   body    red             default         "^Closed #.*"
color   body    brightblue      default         "^Reply to this email.*"

Opinion

As Drew DeVault mentioned in his blog, the design/intention of "Always Online" is less than ideal when it comes to no internet connection scenarios. Frankly speaking, it rarely happens to me here in China. So I prefer using Aerc with its "Always Online" feature enabled. (though waiting for several seconds for connection is annoying compared to NeoMutt's offline mode) On the other hand, NeoMutt with Mutt-Wizard is a solid choice, when the Internet connection is unstable. Also as Drew DeVault said, you can use more than one email clients depending on your actual situation. So this is my strategy for using terminal email clients: use Aerc when the Internet connection is stable, and NeoMutt when it is not.

Expectations

I was wondering if there's a way that one email system can download emails from IMAP server to the local storage, so that when I open the email client, I can read emails offline without delay. After opening and showing all the local emails, the client would automatically sync with the server in the background, downloading new emails and uploading emails. If we could do this in the terminal email clients, that would be perfect. Or maybe it is already achieved? If you know how to do this, please let me know.

See also

1. The official website of Aerc
2. The official source code of Aerc
3. The official website of NeoMutt
4. The official repo of NeoMutt
5. aerc, mbsync, and postfix for maximum comfy offline email by Drew DeVault
6. Email with Aerc by Julio Loayzam
7. Configuring aerc for git via email by Drew DeVault
8. The advantages of an email-driven git workflow by Drew DeVault
9. Git send email tutorial
10. Initial pre-release of aerc: an email client for your terminal by Drew DeVault
11. Use Plaintext Email - A guide to using plain text email effectively


  1. Check this classic blog for more information about mailing lists vs GitHub.
  2. Originally from this.

Back to index