I/O IMAP

IMAP client library, written in Rust
This library is composed of 3 feature-gated layers:
- Low-level I/O-free coroutines: these
no_std-compatible state machines contain the whole IMAP logic and can be used anywhere - Mid-level light client: a standard, blocking IMAP client using a
Stream: Read + Write - High-level full client: light client + TCP connections and TLS negotiations handled for you
Table of contents
Features
- I/O-free coroutines:
no_stdstate machines; no sockets, no async runtime, nostdrequired, drive against any blocking, async, or fuzz harness. - Light standard, blocking client (requires
clientfeature) - Full standard, blocking client with TLS support:
- Rustls with ring crypto (requires
rustls-ringfeature) - Rustls with aws crypto (requires
rustls-awsfeature) - Native TLS (requires
native-tlsfeature)
- Rustls with ring crypto (requires
- SASL mechanisms:
ANONYMOUS,LOGIN,PLAIN,XOAUTH2andOAUTHBEARERbuilt-inSCRAM-SHA-256(requiresscramfeature)
- IMAP extensions:
IDLE,CONDSTORE,QRESYNCetc (see RFC coverage)
[!TIP] I/O IMAP is written in Rust and uses cargo features to gate backend support. The default feature set is declared in Cargo.toml or on docs.rs.
RFC coverage
| Module | What it covers |
|---|---|
| 2177 | IDLE: push notification extension |
| 2971 | ID: server/client identification extension |
| 3501 | IMAP4rev1: greeting, capability, login/logout, list/lsub/status, create/delete/rename/subscribe/unsubscribe, select/examine/close/check/expunge, fetch/store/search/copy/append, noop, starttls |
| 3691 | UNSELECT: discard mailbox state without expunge |
| 4315 | UIDPLUS: APPENDUID and COPYUID response codes |
| 5161 | ENABLE: capability activation extension |
| 5256 | SORT and THREAD: server-side message sorting and threading |
| 6851 | MOVE: atomic message move extension |
| 7162 | CONDSTORE / QRESYNC: CHANGEDSINCE / VANISHED FETCH modifiers and CONDSTORE / QRESYNC SELECT and EXAMINE parameters for fast incremental resync (obsoletes RFC 4551 CONDSTORE and original RFC 5162 QRESYNC) |
| 7628 | OAUTHBEARER: OAuth 2.0 bearer token SASL mechanism; also XOAUTH2 |
| 7677 | SCRAM-SHA-256: SASL SCRAM-SHA-256 mechanism (feature scram) |
Usage
I/O IMAP can be consumed at three layers, depending on how much of the I/O stack you want to own:
- Coroutines:
no_std-friendly state machines. You own the socket and the bytes; the library produces commands and parses responses. Works under any blocking, async, or fuzz harness. - Light client (
clientfeature): aRead + Writewrapper exposing one method per IMAP command. You still open the socket and negotiate TLS, then hand over a ready stream. - Full client (
rustls-ring/rustls-aws/native-tls): TCP, TLS, greeting and SASL handled for you; pass in a URL + SASL config, get back an authenticated session.
Every coroutine implements the ImapCoroutine trait (crate::coroutine). resume(&mut Fragmentizer, Option<&[u8]>) returns ImapCoroutineState<Yield, Return>:
Yielded(y): intermediate progress. The standardImapYieldisWantsRead(caller reads more bytes and feeds them back; passSome(&[])on EOF) orWantsWrite(Vec<u8>)(caller writes these bytes; next resume usually takesNone). Coroutines that surface domain events (ImapIdle,ImapMailboxWatch) declare their ownYieldenum with an extraEvent(...)variant.Complete(result): terminal payload,Result<Output, Error>.
The three snippets below all connect to a server (HOST / PORT env vars; URL for the full client), read the greeting, and print the CAPABILITY list. They are the verbatim sources of cargo run --example <name>.
Coroutine
No io-imap features required. The same shape works under async or fuzz harnesses, only the I/O glue changes.
use ;
use ;
use ;
use ConfigVerifierExt;
[!INFO] See the tokio-based alternative at examples/tokio_coroutine.rs.
Light client
Enable the client feature. ImapClientStd::new(stream) wraps any blocking Read + Write and exposes one method per IMAP command. You still open the TCP socket, negotiate TLS, authenticate; the client takes it from there.
[]
= { = "0.1.0", = false, = ["client"] }
use ;
use ImapClientStd;
use ;
use ConfigVerifierExt;
Full client
Enable one of the TLS feature flags: rustls-ring (default), rustls-aws, or native-tls. ImapClientStd::connect(url, tls, starttls, sasl, auto_id) opens imap:// (plain TCP) or imaps:// (implicit TLS) via pimalaya/stream, drives the optional STARTTLS upgrade, reads the greeting + capability list, and runs the chosen SASL mechanism, returning a ready-to-use authenticated client.
[]
= { = "0.1.0", = false, = ["rustls-ring"] }
use ;
use ImapClientStd;
use ;
use Url;
The sasl argument is Option<impl Into<Sasl>>, so any of the per-mechanism structs (SaslLogin, SaslPlain, SaslAnonymous, SaslOauthbearer, SaslXoauth2, SaslScramSha256 behind the scram feature) can be passed in Some(...) directly without wrapping in a Sasl variant.
Examples
See the complete examples at ./examples.
Have also a look at real-world projects built on top of this library:
- Himalaya CLI: CLI to manage emails
- Himalaya TUI: TUI to manage emails
- Neverest: CLI to synchronize emails
- Mirador: CLI to watch mailbox changes and fire hooks on every event
- Sirup: CLI to spawn pre-authenticated IMAP/SMTP sessions and expose them via Unix sockets
AI disclosure
This project is developed with AI assistance. This section documents how, so users and downstream packagers can make informed decisions.
-
Tools: Claude Code (Anthropic), Opus 4.7, invoked locally with a persistent project-scoped memory and a small set of repo-specific rules.
-
Used for: Refactors, mechanical multi-file edits, boilerplate (feature gates, error enums, derive macros, trait impls), test scaffolding, doc polish, exploratory design conversations.
-
Not used for: Engineering, critical code, git manipulation (commit, merge, rebase…), real-world tests.
-
Verification: Every AI-assisted change is read, compiled, tested, and formatted before commit (
nix develop --command cargo check / cargo test / cargo fmt). Behavioural correctness is verified against the relevant RFC or upstream spec, not assumed from the model output. Tests are never adjusted to fit AI-generated code; the code is adjusted to fit correct behaviour. -
Limitations: AI models occasionally produce code that compiles and passes tests but is subtly wrong: off-by-one errors, missed edge cases, plausible but nonexistent APIs, stale RFC references. The verification workflow catches most of this; it does not catch all of it. Bug reports are welcome and taken seriously.
-
Last reviewed: 29/05/2026
License
This project is licensed under either of:
at your option.
Social
- 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 → 2023: NGI Assure
- 2023 → 2024: NGI Zero Entrust
- 2024 → 2026: NGI Zero Core
- 2027 in preparation…
If you appreciate the project, feel free to donate using one of the following providers:
