Email Client for Notmuch an email client based on notmuch indexing tool that is inspired from Gmail
Support Development
PayPal ● 
Bitcoin Address: bc1qh7juzrxrawpr65elm4qs285m5rdhnhgsn7h2jf
Lightning Address:
Your Input Matters
The "Email Client for Notmuch" extension brings a Gmail like email client to your offline email accounts using the powerful Notmuch email indexing command-line tool. In the simplest form, this extension is just a graphical user interface for the Notmuch tool but it can be enhanced by using shell scripts to perform different actions. For instance, you can define a periodic job for the extension and ask it to display the output of the batch script in the toolbar area. This can be used to run a command-line email fetcher (like the powerful offlineimap command-line email fetcher), then run Notmuch to index the newly fetched emails and finally ask Notmuch to print the total number of unread emails into the stdout which will be shown in the badge area.



  1. What is "notmuch"?

    "notmuch" is a command-line email indexing tool. You need to have it configured before trying to use this extension. See for more info!

  2. What is Maildir?

    Maildir is a file structure format that is commonly used to store email files locally. This extension assumes your emails are located inside a root directory and are stored in the Maildir format. Read for more info.

  3. What is the "Email Client for Notmuch" extension and how does it work?

    This extension brings the power of notmuch email client to your browser. Basically, it is a GUI for this command-line email indexing tool. When the extension is installed a toolbar button is added to your browser. Clicking on this button opens the actual email client UI. On the first install, you will be asked to install a native client which allows the extension to communicate with the notmuch email client. Note that this extension assumes you have a working configuration for your notmuch email client. When the native client is installed, click the toolbar button once again to open the client. When the client is opened, it will ask notmuch to provide the root directory for user emails. This is stored in your notmuch configuration file ([database] > path) and can be seen by running "notmuch config get database.path" command. The extension GUI has three sections: "Search", "Tree", and "List" views. When the root directory is resolved, the "Tree" view will list all directories in this root directory and displays them in a tree-like style on the left side of the client GUI (note that a "." in folder name is considered as a child node). select a folder from this list causes the "List" view to load emails that match with "path:folder-path/**" query. Basically this will result in displaying all the emails that are located in the selected folder in the "List" view. You can switch to a different folder by selecting it from the "Tree" view. In the "Search" view you can search for any notmuch compatible queries (results will be shown in the "List" view).

  4. I am a Windows user. Can I use this email client?

    If you have Windows 10, yes! You can use the built-in Linux subsystem. For more information check WSL installation guide; it is recommended to use Ubuntu distribution. Note that as of version 0.2.8, in the Windows OS, all the commands are prefixed with C:\Windows\System32\wsl.exe. So if you want to run a shell script to archive emails on the options page (e.g.: use /path/to/ [threads] [query]) where the path is meant to work on the Linux subsystem. But the actual command that will be executed is C:\Windows\System32\wsl.exe /path/to/ [threads] [query]. So basically you need to install a preferred Linux subsystem in your Windows 10, then install the "notmuch" program and configure it. You can use this email client to view your emails!

  5. What's new in this version?

    Please check the Logs section.

  6. Can I ask the extension to display the number of unread emails in the toolbar badge area?

    Yes, basically this extension is capable of running a single OS-level command (or multiple commands located in a shell script) once per pre-defined interval and display the result in the badge area. This can be used to display the number of unread emails and update the counter once per while. To do so, open the options page and fill the "command" variable with the path to an executable (a sample is provided below). This script will be called once per 5 minutes by default with a single argument which is either "true" or "false". "true" means the extension expects the script to optionally run a server synchronization job and then return the count. "false" means there is no need for a server synchronization job.

    Here is a sample script that uses "offlineimap" command-line tool to fetch new emails and uses notmuch to find the number of unread emails.

    if [ $1 = "true" ]; then
      /usr/local/bin/offlineimap -u quiet &> /dev/null;
      /usr/local/bin/notmuch new &> /dev/null
    /usr/local/bin/notmuch count --output=threads path:/.*/INBOX/ tag:unread

    $1 will be the sync argument. If the extension asks for synchronization, then offlineimap is executed with "-u quiet" to prevent any std prints. To make sure there will be no std prints use "&> /dev/null;" as well. When syncing is over, a silent "notmuch new" is called to make sure database is updated. Now "notmuch count" is called to calculate the total number of unread emails in the INBOX folder. Note that in this example RegExp is used to find the matching folder. You can simply use the relative path for a faster operation.

    Note: The extension always requests syncing unless this is a sync request from the right-click context menu or a message is tagged from the "List" UI.

    Note: You can change the interval of this periodic job by altering the "interval" variable in the options page. The minimum acceptable value is 1 minutes.

    Note: When a request for executing the external script is placed, there will be a delay before actually running the script. The default value is (delay = 2 seconds). You can change this value from the options page.

  7. Can I use this extension to "archive" messages like what I do in the Gmail UI?

    Yes! but you need to first define what the archive means! Go to the options page and find the "archive" variable and define an OS-level command or shell script for it. Here is a sample:

    create "" executable file with the following content:

    if [[ $# -eq 0 ]] ; then
      echo 'no input query'
      exit 1
    /usr/local/bin/notmuch search --output=files $* | xargs -I % sh -c 'mv % /path-to-a-maildir-directory/cur/'
    /usr/local/bin/notmuch new

    In this script, "notmuch" is used to search a query which is passed by the extension to this shell script and for matching files (note the –-output=files argument) "mv" command is used to actually move the file to a new destination.

    Now set the "archive" variable in the options page to "archive.action = / [threads] [query]".

    Note: for all the user-action commands the extension replaces the “[threads]” keyword with the current selected threads in the “List” view and “[query]” keyword with the search query that is displayed in the “Search” view. The combination of these two queries will result in those files that match with the search query that are located in the current folder. So if a thread has several emails in it where some emails are located in another folder, this query only matches these emails that are located in the current folder."

  8. I am pressing the "Trash" button but the actual email file is still in the folder. Am I doing something wrong?

    When the "Trash" button is pressed, the extension finds the matching emails and adds "deleted" tag to them. Notmuch will ignore those emails in the search result but the emails are still in the folders! To actually delete the emails you need to use "notmuch search" to find all the emails with the "deleted" tag and then actually delete them or move them to a trash-like folder. You can do this in by defining a new custom-command as described below.

  9. Is it possible to run a custom command based on the search query?

    Yes, on the options page, there is a variable called "commands". Add a custom name to this array (say "delete"). now add a new variable with this name to the options page as follows:

    "commands": ["delete"],
    "delete": {
      "name": "Move deleted emails to Trash",
      "action": "/path-to-the-trash-script/",
      "classList": [],
      "alert": true,
      "warn": "Are you sure?"

    Now refresh the client. In the extra menu, you will get a new list item called “Move deleted emails to Trash”. When this item is clicked, the “” script is called. Like the “archive” command you can also pass “[thread]” and “[query]” arguments to the executable.

    Note: the "classList" key is an array object. If this array has "selection" keyword in it, then the added item is only enabled when there is a selection in the “List” view. Use it when the action is related to the selected threads.

    Note: alert=true will display an alert box when the script returns non-zero code (an error code)

    Note: if “warn” key is defined, then you will get a confirmation box before actually executing the external script.

    Sample of ""

    /usr/local/bin/notmuch search --output=files tag:deleted | xargs -I % sh -c "mv % /path-to-a-trash-maildir-direcotry/cur/"
    /usr/local/bin/notmuch tag -deleted +ignored tag:deleted
    /usr/local/bin/notmuch new

    Note that if the output of the command returns threads as "thread:..." formart, those threads will be selected in the list UI after the command is executed. You can use this method to find for instance spam emails. Just run the external command that detects threads that are likely spammed and then ask the external command to return threads. When the command is executed, those threads that match the output of the external command will be selected.

  10. In Gmail, some tags are colorful. Can I do the same with this email client?

    Yes, each tag element has a dataset value. You can use it as a selector to find the element and apply a custom style to it. For instance let's style "replied" tag elements. Add the following CSS rule to the "list view" module from the options page:

    [data-tag=replied] {background-color: #ebdbde!important; color: #662e37 !important;}

  11. Is it possible to have colorful email threads like what we can do in Thunderbird?

    Yes, each thread-entry in the list view has all its tags listed in the "tags" dataset attribute. You can use this attribute to change styling of this entry. For instance let's have the "red" tag change the background color of the entry to red. Add the following CSS rule to the "list view" module from the options page:

    [data-tags\*=red] {background-color: #fffafb !important; color: #942335 !important; font-weight: normal !important;}
    [data-tags*=red] [data-tag] {border: solid 1px #e6cbcb}

    The first rule is to change the color and background color of the entry. The second rule changes the style of all tag elements for this entry.

  12. I have accidentally clicked an action and now I need to undo it. Any option for that?

    There is no real undo button in this extension. It is pretty hard to undo a user-action for instance. Though you can ask the list view to return the last 30 actions and the query that is used for these actions. Let' say you have accidentally deleted an important email. Use the Extra -> Copy last 30 actions button. Paste the result in a notepad and find the thread id. Now search for that thread id and move it back. Note that you might need to select at least one email for the "Copy last 30 actions" to be enabled (this is a bug and will be fixed soon).

  13. Why I don't see the entire thread when I open an email?

    An entire thread might be huge and may take sometime to be fetched. Normally you need those emails that are matched with the current search result. Anyhow if you need the entire thread, use Shift key while clicking on the "Open" button.

  14. How can I reply to an email?

    As of version 0.2.7, there is a reply button. Click the button to prepare a reply (to reply to all senders use Shift + Click). You can edit all parts and then hit the "Reply" button to send your message. To send a message you need a command-line program that can send emails. For instance lets configure Swaks - Swiss Army Knife for SMTP to send the replies.

    Open options page and edit the reply object as follows:

    "reply": {
      "accounts": [],
      "action": "path-to/ \"[from]\" \"[to]\" \"[body]\"  \"[subject]\" \"[in-reply-to]\" \"[references]\""

    where the "" looks like this:

    if [[ $# -eq 0 ]] ; then
      echo 'no input query' >&2
      exit 1
    email=$(echo $1 | grep -i -o '[A-Z0-9._%+-]\+@[A-Z0-9.-]\+\.[A-Z]\{2,4\}')
    if [[ $email == ]]
    if [[ -z "$server" ]]
      echo 'no server for '"$email" >&2
      exit 1
    /usr/local/bin/swaks swaks -server $server \
      -tls --auth-user "$1" --auth-password $password \
      --to "$2" \
      --from "$1" \
      --body "$3" \
      --add-header "MIME-Version: 1.0" --add-header "Content-Type: text/html" \
      --header "Subject: $4" \
      --header "In-reply-to: $5" \
      --header "References: $6"

    Note: The Bash script first checks the sender ($1) and then prepares the SMTP server and password based on the email address. If you have multiple accounts, define them here.

    Note: The client prepares the HTML body and passes it to the "[body]". All requeired fields are passed to the "" script and it handles the actual server communicatation. If you have multiple accounts, use reply.accounts array with the email addresses so that you can select them from the UI.

  15. Can I sort emails in the list view?

    On the options page you can define how emails are sorted in the list view. There are three options: flagged: to view flagged emails first, subject-az: to sort based on subjects (a to z), subject-za: to sort based on subjects (z to a)

  16. I prefer to view emails in the right-size panel instead of the current popup mode. Is this possible to rearrange elements to have this view?

    Use the following CSS code for the client view:

    @media (min-width: 1400px) {
      #popup {
          position: unset;
          padding: 0;
          border-left: solid 1px #e1e1e1;
          width: 45vw;

    This will cause the show module to appear in the popup mode only when the viewport size is less that 1400px. You can change the value to fit your screen.

  17. My operating system creates a specific file in every folder (for instance Mac OS create a .DS_Store file on every folder that is browsed by the user). Since this file is not a maildir compatible file, my notmuch throws an error. How can I ask notmuch to ignore these files?

    add ignore=.DS_Store to the [new] section of the .notmuch-config file to ignore this file type. If you have multiple file types use ";" for separation.

  18. Is it possible to have multiple list views to view different notmuch queries simultaneously in the screen?

    Yes, you can create an empty folder anywhere in your maildir and place a file named query in this folder. In the query file insert each query per line, then refresh your extension. When the folder name is pressed in the tree view, the extension fetches the queries from the query file and displays each query line in a new list view. You can have as many queries as you would like to; however, to have them fit in your screen it is recommended to have a maximum of three list views per query file. Note that you can write a complex query to mix several queries in one view. Having multiple list views per single folder is called "smart label" which is a very powerful tool to organize how the extension manages your list view. Note that since the query file is not an email file, you need to add it into the notmuch's ignore list.

  19. My email database is really big and notmuch new command that is used inside the custom commands take too long. So the action is not resolving. Since the UI waits for the custom command to finish, it does not update as well. Is there any way to improve the execution speed of the custom commands that need notmuch new inside them?

    For custom commands to modify the database, you will need to ask notmuch to check folder structure for changes. Usually notmuch new works just fine. When this command is executed, the email client can now pass the current search query to the notmuch executable again to be notified about the modifications. So there is no way to get the correct results after a custom command modifies the database without first asking notmuch to reindex. If notmuch new is not fast enough, you can use notmuch reindex $* inside the custom command's script which only reindexes the currently matched queries ("$*" passes the entire query that is passed to script to the reindexing module). This way notmuch knows all the changes in the current view without actually reindexing the entire folder tree. Note that this method only indexes the current query so if for instance you have a trash command that moves emails to another directory, by running this command only the current query is indexed and emails in the destination directory are not yet indexed. It is recommended to run notmuch new afterwards and to let the extension stop waiting for the script to finish execution, print [fake-resolve] keyword to the stdout. Basically, when the "[fake-resolve]" keyword is seen in the stdout, the extension pretends the execution is finished (without actually terminating the execution). Here is a sample bash script that uses this technique. Note that this method only works on version >= 0.4.4.

    /usr/local/bin/notmuch reindex $*
    echo [fake-resolve]
    /usr/local/bin/notmuch new

  20. Can I change the view's appearance (like mark selected threads as read or unread or hide them) on an action before the actual action is performed for faster user interaction?

    As of version 0.4.7, fake actions are supported. For custom commands, add a new key to the action's object called fake. The value is comma-separated list of supported fake actions (read, unread, and hide) in string format (e.g.: {...fake: 'read, hide'...}). For default commands use the config.fake preference on the options page. Note that the fake actions are not actual actions. They can be only used to temporary update the list view before the actual action is executed. For instance, if some threads get archived, the normal command may take some time since there are multiple actions to be performed. In this case, a fake action can temporarily hide the to-be-archived threads before the command execution completes and the UI updates accordingly. The fake actions can be used instead of the fake-resolve method for faster resolving

Matched Content


Please keep reviews clean, avoid improper language, and do not post any personal information. Also, please consider sharing your valuable input on the official store.

What's new in this version

Change Logs:
    Last 10 commits on GitHub
    Hover over a node to see more details

    Need help?

    If you have questions about the extension, or ideas on how to improve it, please post them on the  support site. Don't forget to search through the bug reports first as most likely your question/bug report has already been reported or there is a workaround posted for it.

    Open IssuesIssuesForks

    Permissions are explained

    nativeMessagingto communicate with notmuch command-line tool and to execute native commands (like move files or run a user-action)
    downloadsto offer downloading the native wrapper
    tabsto open the client in a browser tab
    storageto save user preferences
    contextMenusto add context-menu to the browser-action button
    alarmsto setup a recursive job
    api.github.comto download the native client

    Recent Blog Posts