Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
H

himalaya

> 开发工具
Open source

CLI to manage emails

6.8K stars0 likes0 views
WebsiteGitHub

About

CLI to manage emails

Table of contents

  • Features
  • Installation
  • Configuration
  • Usage
  • Interfaces
  • FAQ
  • AI policy
  • License
  • Social
  • Contributing
  • Sponsoring

Features

  • Shared API for mailboxes, envelopes, flags, messages and attachments
  • Protocol-specific APIs exposing each backend's full surface
  • IMAP, SMTP, ManageSieve, JMAP, Gmail (REST API), Microsoft Graph (Outlook / Microsoft 365) support
  • Maildir specs, m2dir specs, pimdir specs support
  • Simple auth support for IMAP, SMTP and ManageSieve (anonymous, login, plain, oauthbearer, xoauth2, scram-sha-256)
  • HTTP auth support for JMAP: basic, bearer
  • TLS support:
    • Rustls with ring crypto
    • Rustls with aws crypto (requires rustls-aws feature)
    • Native TLS (requires native-tls feature)
  • Discovery support:
    • PACC specs
    • Autoconfiguration (Thunderbird) specs
    • SRV DNS lookups rfc6186
    • JMAP session resolution rfc8620
  • SOCKS5, HTTP proxy support via $ALL_PROXY and $HTTP_PROXY
  • TOML configuration with multi-account support
  • JSON output via --json

[!TIP] Himalaya is written in Rust and uses cargo features to gate backend support. The default feature set is declared in Cargo.toml.

Installation

Pre-built binary

Himalaya can be installed with the installer:

As root:

curl -sSL https://raw.githubusercontent.com/pimalaya/himalaya/master/install.sh | sudo sh

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.

For a more up-to-date version than the latest release, check out the releases GitHub workflow and look for the Artifacts section. These pre-built binaries are built from the master branch.

[!NOTE] Such binaries are built with the default cargo features. If you need specific features, please use another installation method.

Cargo

cargo install --locked --git https://github.com/pimalaya/himalaya.git

With only IMAP+SMTP support:

cargo install --locked --git https://github.com/pimalaya/himalaya.git \
  --no-default-features \
  --features imap,smtp,rustls-ring

Arch Linux

From the community repository:

pacman -S himalaya

Or the user repository:

git clone https://aur.archlinux.org/himalaya-git.git
cd himalaya-git
makepkg -isc

Or with yay:

yay -S himalaya-git

Homebrew

brew install himalaya

[!NOTE] Cargo features are not compatible with brew. If you need a different feature set, please use another installation method.

Scoop

scoop install himalaya

Fedora Linux/CentOS/RHEL

From the COPR repo:

dnf copr enable atim/himalaya
dnf install himalaya

Nix

If you have the Flakes feature enabled:

nix profile install github:pimalaya/himalaya

Or run without installing:

nix run github:pimalaya/himalaya

Sources

git clone https://github.com/pimalaya/himalaya
cd himalaya
nix run

Configuration

Run himalaya. With no configuration file on disk, the wizard asks for an email address and discovers the services reachable from it, probing PACC, Thunderbird Autoconfiguration, RFC 6186 SRV and RFC 8620 JMAP resolution in parallel.

Picking one prompts the authentication it advertises, tests the connection, then writes the account to disk.

A persistent configuration is loaded from the first valid path among:

  • $XDG_CONFIG_HOME/himalaya/config.toml
  • $HOME/.config/himalaya/config.toml
  • $HOME/.himalayarc

These are the same paths the himalaya-tui TUI looks at: one TOML file backs both binaries. CLI-only fields and TUI-only sections coexist without errors. See config.sample.toml for a documented template.

Override the path with -c <PATH>; multiple paths can be passed at once, separated by :. The first one is the base and the rest are deep-merged on top.

To add or reconfigure an account, run the bare himalaya wizard again and redirect its printed TOML into (or merge it with) your config file. There is no in-place edit subcommand; himalaya account list and himalaya account check inspect and validate the accounts already declared.

Proton Mail

Proton does not expose IMAP/SMTP directly: run Proton Bridge, which synchronizes mail locally and serves it on a local IMAP/SMTP endpoint. The password is the one generated by the Bridge, not your Proton account password.

[accounts.proton]

imap.server = "imap://127.0.0.1:1143"
imap.sasl.plain.username = "[email protected]"
imap.sasl.plain.password.command = "pass show proton-bridge"

smtp.server = "smtp://127.0.0.1:1025"
smtp.sasl.plain.username = "[email protected]"
smtp.sasl.plain.password.command = "pass show proton-bridge"

To keep TLS on the local link, export the certificate generated by the Bridge and enable STARTTLS:

imap.starttls = true
imap.tls.cert = "/path/to/exported/cert.pem"

smtp.starttls = true
smtp.tls.cert = "/path/to/exported/cert.pem"

Fastmail

Fastmail needs an app password for IMAP/SMTP, or an API token for its native JMAP endpoint.

[accounts.fastmail]

imap.server = "imaps://imap.fastmail.com"
imap.sasl.plain.username = "[email protected]"
imap.sasl.plain.password.command = "pass show fastmail"

smtp.server = "smtps://smtp.fastmail.com"
smtp.sasl.plain.username = "[email protected]"
smtp.sasl.plain.password.command = "pass show fastmail"

To use JMAP instead, replace the imap/smtp blocks with a single jmap one:

jmap.server = "https://api.fastmail.com/jmap/session"
jmap.auth.bearer.token.command = "pass show fastmail"

Gmail

Gmail rejects the account password over SASL PLAIN: generate an app password (requires 2-step verification) and feed it through password.command or password.raw.

[accounts.gmail]

imap.server = "imaps://imap.gmail.com:993"
imap.sasl.plain.username = "[email protected]"
imap.sasl.plain.password.command = "pass show gmail"

smtp.server = "smtps://smtp.gmail.com:465"
smtp.sasl.plain.username = "[email protected]"
smtp.sasl.plain.password.command = "pass show gmail"

mailbox.alias.inbox = "INBOX"
mailbox.alias.sent = "[Gmail]/Sent Mail"
mailbox.alias.drafts = "[Gmail]/Drafts"
mailbox.alias.trash = "[Gmail]/Trash"
mailbox.alias.archive = "[Gmail]/All Mail"

Every Gmail label shows up as a top-level IMAP mailbox, and the special ones live under the [Gmail]/ prefix, so quote them in the shell or reach them through an alias.

[Gmail]/All Mail is the archive holding every message, so aliasing it puts "search everything" one flag away: himalaya envelope search -m archive ....

To use Gmail's native REST API instead of IMAP/SMTP, replace the blocks above with a single OAuth 2.0 bearer token from a helper such as ortie:

gmail.auth.token.command = ["ortie", "token", "show", "-a", "gmail"]

Labels become mailboxes here too, but they carry the API's opaque label ids; address them by name (-m Himalaya-Test) and himalaya resolves the id.

Outlook

Microsoft has retired basic authentication: use OAuth 2.0 via oauthbearer or xoauth2, with the access token supplied by an external helper such as ortie.

[accounts.outlook]

imap.server = "imaps://outlook.office365.com:993"
imap.sasl.xoauth2.username = "[email protected]"
imap.sasl.xoauth2.token.command = ["ortie", "token", "show", "-a", "outlook"]

smtp.server = "smtp://smtp-mail.outlook.com:587"
smtp.starttls = true
smtp.sasl.xoauth2.username = "[email protected]"
smtp.sasl.xoauth2.token.command = ["ortie", "token", "show", "-a", "outlook"]

To use the native Microsoft Graph API instead of IMAP/SMTP, replace the blocks above with a single OAuth 2.0 bearer token (sending goes through Graph too, so no SMTP is needed):

msgraph.auth.token.command = ["ortie", "token", "show", "-a", "msgraph"]

Mail folders carry Graph's opaque folder ids; address them by name (-m Archive) or by a well-known name (-m inbox) and himalaya resolves the id.

Posteo

Standard IMAP and SMTP with your regular account password: no app password required.

[accounts.posteo]

imap.server = "imaps://posteo.de"
imap.sasl.plain.username = "[email protected]"
imap.sasl.plain.password.command = "pass show posteo"

smtp.server = "smtps://posteo.de"
smtp.sasl.plain.username = "[email protected]"
smtp.sasl.plain.password.command = "pass show posteo"

iCloud Mail

Per the iCloud Mail support page, the IMAP login is the name of your address, johnappleseed rather than [email protected], while the SMTP login is the full address.

A dedicated app-specific password is required.

[accounts.icloud]

imap.server = "imaps://imap.mail.me.com:993"
imap.sasl.plain.username = "johnappleseed"
imap.sasl.plain.password.command = "pass show icloud"

smtp.server = "smtp://smtp.mail.me.com:587"
smtp.starttls = true
smtp.sasl.plain.username = "[email protected]"
smtp.sasl.plain.password.command = "pass show icloud"

mailbox.alias.sent = "Sent Messages"

Usage

Every command carries its own --help, the source of truth for its flags and syntax. The snippets below are a taste of the surface.

Shared API

Backend-agnostic commands run on the account's first configured backend, or the one picked with -b/--backend. When an inbox alias is set under [mailbox.alias], -m/--mailbox defaults to it.

himalaya mailbox list
himalaya envelope list --page 2
himalaya envelope search from alice and after 2026-01-01 order by date desc
himalaya flag add --flag seen 1:3,5
himalaya message read 42
himalaya message copy --from INBOX --to Archives 42
himalaya attachment download 42

envelope search uses himalaya's own cross-backend query DSL; its grammar lives in himalaya envelope search --help.

Protocol-specific APIs

Each backend also exposes its full native API under its own subgroup, always against that backend (-b/--backend is ignored here):

himalaya imap raw 'a1 SEARCH FROM "[email protected]"\r\n'
himalaya jmap mailbox query --role drafts
himalaya gmail messages list -q "from:alice is:unread"
himalaya msgraph mail-folders list
himalaya smtp send -f [email protected] -t [email protected] < message.eml
himalaya sieve list
himalaya sieve check --script-file filters.sieve
himalaya sieve put main --script-file filt

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

Rustcliclientemailgpg

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category开发工具
PricingOpen source

> Related tools

V
VS Code
流行的开源代码编辑器
G
Git
分布式版本控制系统
V
Vite
下一代前端构建工具