himalaya
đ Fork
đ Quick Links
đ Project Details
- Primary Language: None
- Languages Used: Rust, Nix, Shell
- License: MIT License
- Created: April 25, 2026
- Last Updated: April 25, 2026
đ About

Table of contents
- Features
- Installation
- Pre-built binary
- Cargo
- Arch linux
- Homebrew
- Scoop
- Fedora Linux/CentOS/RHEL
- Nix
- Sources
- Configuration
- Proton Mail
- Gmail
- Outlook
- iCloud Mail
- Interfaces
- FAQ
- Social
- Sponsoring
Features
- Multi-accounting configuration:
- interactive via wizard (requires
wizardfeature) - manual via TOML-based configuration file (see
./config.sample.toml) - Message composition based on
$EDITOR - IMAP backend (requires
imapfeature) - Maildir backend (requires
maildirfeature) - Notmuch backend (requires
notmuchfeature) - SMTP backend (requires
smtpfeature) - Sendmail backend (requires
sendmailfeature) - Global system keyring for secret management (requires
keyringfeature) - OAuth 2.0 authorization flow (requires
oauth2feature) - JSON output via
--output json - PGP encryption:
- via shell commands (requires
pgp-commandsfeature) - via GPG bindings (requires
pgp-gpgfeature) - via native implementation (requires
pgp-nativefeature)
Himalaya CLI is written in Rust, and relies on cargo features to enable or disable functionalities. Default features can be found in the features section of the Cargo.toml, or on docs.rs.
Installation
Pre-built binary
Himalaya CLI can be installed with the install.sh installer:
As root:
As a regular user:
curl -sSL https://raw.githubusercontent.com/pimalaya/himalaya/master/install.sh | PREFIX=~/.local sh
These commands install the latest binary from the GitHub releases section.
If you want a more up-to-date version than the latest release, check out the releases GitHub workflow and look for the Artifacts section. You will find a pre-built binary matching your OS. These pre-built binaries are built from the master branch.
Such binaries are built with the default cargo features. If you need more features, please use another installation method.
Cargo
Himalaya CLI can be installed with cargo:
With only IMAP support:
You can also use the git repository for a more up-to-date (but less stable) version:
Arch Linux
Himalaya CLI can be installed on Arch Linux with either the community repository:
or the user repository:
If you use yay, it is even simplier:
Homebrew
Himalaya CLI can be installed with Homebrew:
Note: cargo features are not compatible with brew. If you need features like OAuth 2.0, please use a different installation method.
Scoop
Himalaya CLI can be installed with Scoop:
Fedora Linux/CentOS/RHEL
Himalaya CLI can be installed on Fedora Linux/CentOS/RHEL via COPR repo:
Nix
Himalaya CLI can be installed with Nix:
You can also use the git repository for a more up-to-date (but less stable) version:
Or, from within the source tree checkout:
If you have the Flakes feature enabled:
Or, from within the source tree checkout:
You can also run Himalaya directly without installing it:
Sources
Himalaya CLI can be installed from sources.
First you need to install the Rust development environment (see the rust installation documentation):
Then, you need to clone the repository and install dependencies:
Now, you can build Himalaya:
Binaries are available under the target/release folder.
Configuration
Just run himalaya, the wizard will help you to configure your default account.
Accounts can be (re)configured via the wizard using the command himalaya account configure <name>.
You can also manually edit your own configuration, from scratch:
- Copy the content of the documented
./config.sample.toml - Paste it in a new file
~/.config/himalaya/config.toml - Edit, then comment or uncomment the options you want
Proton Mail
When using Proton Bridge, emails are synchronized locally and exposed via a local IMAP/SMTP server. This implies 2 things:
- Id order may be reversed or shuffled, but envelopes will still be sorted by date.
- SSL/TLS needs to be deactivated manually.
- The password to use is the one generated by Proton Bridge, not the one from your Proton Mail account.
[accounts.proton]
email = "example@proton.me"
backend.type = "imap"
backend.host = "127.0.0.1"
backend.port = 1143
backend.encryption.type = "none"
backend.login = "example@proton.me"
backend.auth.type = "password"
backend.auth.raw = "*****"
message.send.backend.type = "smtp"
message.send.backend.host = "127.0.0.1"
message.send.backend.port = 1025
message.send.backend.encryption.type = "none"
message.send.backend.login = "example@proton.me"
message.send.backend.auth.type = "password"
message.send.backend.auth.raw = "*****"
If you still want to use TLS, you need to export the certificate generated by Proton Bridge, then give it to Himalaya:
backend.encryption.type = "start-tls"
backend.encryption.cert = "/path/to/exported/cert.pem"
message.send.backend.encryption.type = "start-tls"
message.send.backend.encryption.cert = "/path/to/exported/cert.pem"
Keeping your password inside the configuration file is good for testing purpose, but it is not safe. You have 2 better alternatives:
- Save your password in any password manager that can be queried via the CLI:
- Use the global keyring of your system (requires the
keyringcargo feature):
Running himalaya account configure proton will ask for your IMAP password, just paste the one generated previously.
Gmail
Google passwords cannot be used directly. There is two ways to authenticate yourself:
Using App Passwords
This option is the simplest and the fastest. First, be sure that:
- IMAP is enabled
- Two-step authentication is enabled
- Less secure app access is enabled
First create a dedicated password for Himalaya.
[accounts.gmail]
email = "example@gmail.com"
folder.aliases.inbox = "INBOX"
folder.aliases.sent = "[Gmail]/Sent Mail"
folder.aliases.drafts = "[Gmail]/Drafts"
folder.aliases.trash = "[Gmail]/Trash"
backend.type = "imap"
backend.host = "imap.gmail.com"
backend.port = 993
backend.login = "example@gmail.com"
backend.auth.type = "password"
backend.auth.raw = "*****"
message.send.backend.type = "smtp"
message.send.backend.host = "smtp.gmail.com"
message.send.backend.port = 465
message.send.backend.login = "example@gmail.com"
message.send.backend.auth.type = "password"
message.send.backend.auth.cmd = "*****"
Keeping your password inside the configuration file is good for testing purpose, but it is not safe. You have 2 better alternatives:
- Save your password in any password manager that can be queried via the CLI:
- Use the global keyring of your system (requires the
keyringcargo feature):
Running himalaya configure -a gmail will ask for your IMAP password, just paste the one generated previously.
Using OAuth 2.0
This option is the most secure but the hardest to configure. It requires the oauth2 and keyring cargo features.
First, you need to get your OAuth 2.0 credentials by following this guide. Once you get your client id and your client secret, you can configure your Himalaya account this way:
[accounts.gmail]
email = "example@gmail.com"
folder.aliases.inbox = "INBOX"
folder.aliases.sent = "[Gmail]/Sent Mail"
folder.aliases.drafts = "[Gmail]/Drafts"
folder.aliases.trash = "[Gmail]/Trash"
backend.type = "imap"
backend.host = "imap.gmail.com"
backend.port = 993
backend.login = "example@gmail.com"
backend.auth.type = "oauth2"
backend.auth.method = "xoauth2"
backend.auth.client-id = "*****"
backend.auth.client-secret.keyring = "gmail-oauth2-client-secret"
backend.auth.access-token.keyring = "gmail-oauth2-access-token"
backend.auth.refresh-token.keyring = "gmail-oauth2-refresh-token"
backend.auth.auth-url = "https://accounts.google.com/o/oauth2/v2/auth"
backend.auth.token-url = "https://www.googleapis.com/oauth2/v3/token"
backend.auth.pkce = true
backend.auth.scope = "https://mail.google.com/"
message.send.backend.type = "smtp"
message.send.backend.host = "smtp.gmail.com"
message.send.backend.port = 465
message.send.backend.login = "example@gmail.com"
message.send.backend.auth.type = "oauth2"
message.send.backend.auth.method = "xoauth2"
message.send.backend.auth.client-id = "*****"
message.send.backend.auth.client-secret.keyring = "gmail-oauth2-client-secret"
message.send.backend.auth.access-token.keyring = "gmail-oauth2-access-token"
message.send.backend.auth.refresh-token.keyring = "gmail-oauth2-refresh-token"
message.send.backend.auth.auth-url = "https://accounts.google.com/o/oauth2/v2/auth"
message.send.backend.auth.token-url = "https://www.googleapis.com/oauth2/v3/token"
message.send.backend.auth.pkce = true
message.send.backend.auth.scope = "https://mail.google.com/"
Running himalaya account configure gmail will complete your OAuth 2.0 setup and ask for your client secret.
Outlook
[accounts.outlook]
email = "example@outlook.com"
backend.type = "imap"
backend.host = "outlook.office365.com"
backend.port = 993
backend.login = "example@outlook.com"
backend.auth.type = "password"
backend.auth.raw = "*****"
message.send.backend.type = "smtp"
message.send.backend.host = "smtp-mail.outlook.com"
message.send.backend.port = 587
message.send.backend.encryption.type = "start-tls"
message.send.backend.login = "example@outlook.com"
message.send.backend.auth.type = "password"
message.send.backend.auth.raw = "*****"
Keeping your password inside the configuration file is good for testing purpose, but it is not safe. You have 2 better alternatives:
- Save your password in any password manager that can be queried via the CLI:
- Use the global keyring of your system (requires the
keyringcargo feature):
Running himalaya account configure outlook will ask for your IMAP password, just paste the one generated previously.
Using OAuth 2.0
This option is the most secure but the hardest to configure. First, you need to get your OAuth 2.0 credentials by following this guide. Once you get your client id and your client secret, you can configure your Himalaya account this way:
[accounts.outlook]
email = "example@outlook.com"
backend.type = "imap"
backend.host = "outlook.office365.com"
backend.port = 993
backend.login = "example@outlook.com"
backend.auth.type = "oauth2"
backend.auth.client-id = "*****"
backend.auth.client-secret.keyring = "outlook-oauth2-client-secret"
backend.auth.access-token.keyring = "outlook-oauth2-access-token"
backend.auth.refresh-token.keyring = "outlook-oauth2-refresh-token"
backend.auth.auth-url = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize"
backend.auth.token-url = "https://login.microsoftonline.com/common/oauth2/v2.0/token"
backend.auth.pkce = true
backend.auth.scopes = ["https://outlook.office.com/IMAP.AccessAsUser.All", "https://outlook.office.com/SMTP.Send"]
message.send.backend.type = "smtp"
message.send.backend.host = "smtp.mail.outlook.com"
message.send.backend.port = 587
message.send.backend.starttls = true
message.send.backend.login = "example@outlook.com"
message.send.backend.auth.type = "oauth2"
message.send.backend.auth.client-id = "*****"
message.send.backend.auth.client-secret.keyring = "outlook-oauth2-client-secret"
message.send.backend.auth.access-token.keyring = "outlook-oauth2-access-token"
message.send.backend.auth.refresh-token.keyring = "outlook-oauth2-refresh-token"
message.send.backend.auth.auth-url = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize"
message.send.backend.auth.token-url = "https://login.microsoftonline.com/common/oauth2/v2.0/token"
message.send.backend.auth.pkce = true
message.send.backend.auth.scopes = ["https://outlook.office.com/IMAP.AccessAsUser.All", "https://outlook.office.com/SMTP.Send"]
Running himalaya account configure outlook will complete your OAuth 2.0 setup and ask for your client secret.
iCloud Mail
From the iCloud Mail support page:
- IMAP port =
993. - IMAP login = name of your iCloud Mail email address (for example,
johnappleseed, notjohnappleseed@icloud.com) - SMTP port =
587withSTARTTLS - SMTP login = full iCloud Mail email address (for example,
johnappleseed@icloud.com, notjohnappleseed)
[accounts.icloud]
email = "johnappleseed@icloud.com"
backend.type = "imap"
backend.host = "imap.mail.me.com"
backend.port = 993
backend.login = "johnappleseed"
backend.auth.type = "password"
backend.auth.raw = "*****"
message.send.backend.type = "smtp"
message.send.backend.host = "smtp.mail.me.com"
message.send.backend.port = 587
message.send.backend.encryption.type = "start-tls"
message.send.backend.login = "johnappleseed@icloud.com"
message.send.backend.auth.type = "password"
message.send.backend.auth.raw = "*****"
folder.aliases.sent = "Sent Messages"
Keeping your password inside the configuration file is good for testing purpose, but it is not safe. You have 2 better alternatives:
- Save your password in any password manager that can be queried via the CLI:
- Use the global keyring of your system (requires the
keyringcargo feature):
Running himalaya account configure icloud will ask for your IMAP password, just paste the one generated previously.
Interfaces
These interfaces are built at the top of Himalaya CLI to improve the User Experience:
- pimalaya/himalaya-vim: Vim plugin
- dantecatalfamo/himalaya-emacs: Emacs plugin
- jns/himalaya: Raycast extension
- openclaw/openclaw: OpenClaw SKILL
- parisni/dfzf: dfzf integration
FAQ
How different is it from aerc, mutt or alpine?
Aerc, mutt and alpine can be categorized as Terminal User Interfaces (TUI). When the program is executed, your terminal is locked into an event loop and you interact with your emails using keybinds. Himalaya is also a TUI, but more specifically a Command-Line Interface (CLI). There is no event loop: you interact with your emails using shell commands, in a stateless way. Additionaly, Himalaya CLI is based on `email-lib`, which is also part of the Pimalaya project. The aim is not just to propose a new terminal interface, but also to expose Rust tools to deal with emails. Anyone who knows Rust language can build his own email interface, without re-inventing the wheel.How to compose a message?
An email message is a list of **headers** (`key: val`) followed by a **body**. They form together a template: ***Headers and body must be separated by an empty line.*** ### Headers Here a non-exhaustive list of valid email message template headers: - `Message-ID`: represents the message identifier (you usually do not need to set up it manually) - `In-Reply-To`: represents the identifier of the replied message - `Date`: represents the date of the message - `Subject`: represents the subject of the message - `From`: represents the address of the sender - `To`: represents the addresses of the receivers - `Reply-To`: represents the address the receiver should reply to instead of the `From` header - `Cc`: represents the addresses of the other receivers (carbon copy) - `Bcc`: represents the addresses of the other hidden receivers (blind carbon copy) An address can be: - a single email address `user@domain` - a named address `NameFrom: alice@localhost
To: bob@localhost
Subject: MML simple
<#multipart type=alternative>
This is a plain text part.
<#part type=text/enriched>
<center>This is a centered enriched part</center>
<#/multipart>
Subject: MML simple
To: bob@localhost
From: alice@localhost
MIME-Version: 1.0
Date: Tue, 29 Nov 2022 13:07:01 +0000
Content-Type: multipart/alternative;
boundary="4CV1Cnp7mXkDyvb55i77DcNSkKzB8HJzaIT84qZe"
--4CV1Cnp7mXkDyvb55i77DcNSkKzB8HJzaIT84qZe
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
This is a plain text part.
--4CV1Cnp7mXkDyvb55i77DcNSkKzB8HJzaIT84qZe
Content-Type: text/enriched
Content-Transfer-Encoding: 7bit
<center>This is a centered enriched part</center>
--4CV1Cnp7mXkDyvb55i77DcNSkKzB8HJzaIT84qZe--
How to add attachments to a message?
*Read first about the FAQ: How to compose a message?*. *See more examples at [pimalaya/core/mml](https://github.com/pimalaya/core/tree/master/mml/examples).*How to debug Himalaya CLI?
The simplest way is to use `--debug` and `--trace` arguments. The advanced way is based on environment variables: - `RUST_LOG=How the wizard discovers IMAP/SMTP configs?
All the lookup mechanisms use the email address domain as base for the lookup. It is heavily inspired from the Thunderbird [Autoconfiguration](https://udn.realityripple.com/docs/Mozilla/Thunderbird/Autoconfiguration) protocol. For example, for the email address `test@example.com`, the lookup is performed as (in this order): 1. check for `autoconfig.example.com` 2. look up of `example.com` in the ISPDB (the Thunderbird central database) 3. look up `MX example.com` in DNS, and for `mx1.mail.hoster.com`, look up `hoster.com` in the ISPDB 4. look up `SRV example.com` in DNS 5. try to guess (`imap.example.com`, `smtp.example.com`âĻ)How to disable color output?
Simply set the environment variable NO_COLOR=1Social
- Chat on Matrix
- News on Mastodon or RSS
- Mail at pimalaya.org@posteo.net
Sponsoring
Special thanks to the NLnet foundation and the European Commission that have been financially supporting the project for years:
- 2022: NGI Assure
- 2023: NGI Zero Entrust
- 2024: NGI Zero Core (still ongoing in 2026)
If you appreciate the project, feel free to donate using one of the following providers:
âšī¸ Fork Information
This is a fork of another repository.
