The Problem

Email lives in many incompatible worlds: IMAP, JMAP, Gmail's REST API, Microsoft Graph, and local Maildir folders. Each has its own auth flows, search syntax, and flag semantics. A CLI that only speaks one protocol locks users into a provider; a CLI that tries to bolt them together usually ends up with a leaky abstraction that only handles the common 20% of each backend's capabilities.

What This Does

himalaya is a Rust CLI for managing email across IMAP, SMTP, JMAP, Gmail REST, Microsoft Graph, Maildir, and m2dir backends. The architecture is two-tier: a shared API (src/backend.rs, src/email/) for mailboxes, envelopes, flags, messages, and attachments, plus protocol-specific modules (src/imap/, src/jmap/, src/gmail/) that expose each backend's full surface—Gmail labels, JMAP identities, IMAP raw commands.

The cairn/ directory holds design docs and change proposals, effectively a living spec for how the project evolves. src/account/ handles multi-account configuration and the account-level CLI dispatch.

How It Is Wired

Execution starts at main in src/main.rs:102, which reaches 227 functions. It delegates to execute in src/account/cli.rs:25, the central dispatcher that reaches 226 functions and is called from one place. From there, the call graph fans out to backend-specific handlers.

The hottest functions—the ones with the widest blast radius—are parse (called from 21 places), map_color_or (19), and any (15). execute itself makes 35 calls to table_preset and 22 to table_arrangement, so any change to table formatting ripples through every list command.

Network and database effects are close to the entry point. The shortest traced path is main -> execute, which reads/writes a database via client.fetch and makes network calls via client.delete. execute -> get_message reaches the network via self.fetch in two hops. src/imap/backend.rs owns the IMAP network calls (39 functions), src/gmail/backend.rs owns Gmail's (18), and src/account/check.rs does both database and network work for account probing.

The graph shows no circular dependencies and no internal module hub—the code is flat, with src/config.rs (25 functions) and src/account/context.rs (47 functions) being the shared touchpoints.

How To Use It

Setup:

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

Configuration: Create a TOML config file (see config.sample.toml). Multi-account setup lives there, with per-account backend, auth, and TLS settings. No environment variables are required; $ALL_PROXY and $HTTP_PROXY are honored if present.

Running it: Invoke the himalaya binary. Commands follow the pattern himalaya account list, himalaya envelope list, etc. --json flag gives machine-readable output. The wizard (src/wizard/discover.rs) can auto-discover account settings via DNS SRV and autoconfiguration.

Real-World Use

A user with a Fastmail account (JMAP) and a work Gmail account configures both in config.toml. They run himalaya envelope list -a work to see inbox, himalaya message save to draft, and himalaya message send to send via SMTP. The shared API means the same commands work against either backend; the protocol-specific modules let them use Gmail labels or JMAP identities when needed.

Code Health & Issues

Static analysis found 20 findings: 2 high, 18 medium. The high-severity items are deep nesting (max indentation depth 8, e.g., src/gmail/settings/sendas.rs) and 324 duplicated 6-line code blocks across 111 files. Medium items include an oversized src/imap/backend.rs (645 lines) and high branching density in src/jmap/client.rs and src/smtp/client.rs (35 branch points over 110 lines).

SDLC observations from the file structure:

  • High - CI workflows pin third-party actions to @master (e.g., pimalaya/nix/.github/workflows/audit.yml@master) instead of commit SHAs; a moved tag could execute arbitrary code with your token.
  • High - No test files exist despite 248 source files; the 25 "test files" are test plans in cairn/spec/testing/, not Rust tests.
  • High - CI workflows declare no permissions for GITHUB_TOKEN and no timeout-minutes.
  • Medium - No Dependabot/Renovate config; no dependency vulnerability scan in CI.

The Bottom Line

A genuinely capable multi-backend email CLI with a clean two-tier architecture. The codebase is flat and navigable, but the duplicated blocks and deep nesting will make changes tedious. Worth using if you need one tool across IMAP/JMAP/Gmail; worth contributing to only if you accept the testing gap and CI hygiene debt.