Agnostic is a Rust ecosystem that provides runtime-agnostic abstractions for async operations. Write your async code once and run it seamlessly with tokio, smol, or even in WebAssembly - without code changes.
- Runtime Independence: Switch between tokio, smol with a single feature flag
- Zero-Cost Abstractions: Generic implementations compile to specialized code per runtime
- Incremental Adoption: Use lightweight
agnostic-liteor the full-featuredagnosticcrate - no_std Support: Core abstractions work in embedded and constrained environments
- Memory Safe: No unsafe code in core abstractions (
agnostic-lite) - Comprehensive: Covers spawning, networking, DNS, process management, and more
The Agnostic ecosystem is organized into modular crates:
agnostic (facade - full-featured)
├── agnostic-lite (core - no_std, alloc-free)
│ ├── Task spawning (AsyncSpawner, AsyncLocalSpawner)
│ ├── Time abstractions (AsyncSleep, AsyncInterval, AsyncTimeout)
│ └── Runtime implementations (tokio, smol, wasm)
├── agnostic-io (Sans-I/O trait definitions)
│ └── AsyncRead, AsyncWrite, etc.
├── agnostic-net (networking)
│ ├── TCP (TcpListener, TcpStream)
│ ├── UDP (UdpSocket)
│ └── Depends on: agnostic-lite, agnostic-io
├── agnostic-dns (DNS resolution)
│ ├── Multiple transports (DoH, DoT, DoQ, DoH3)
│ ├── DNSSEC support
│ └── Depends on: agnostic-net, hickory-dns
└── agnostic-process (subprocess management)
├── Command execution
├── Stdio redirection
└── Depends on: agnostic-io
| Crate | Version | Description | Use When |
|---|---|---|---|
agnostic |
0.8.0 | Full-featured facade with networking, DNS, process management, QUIC | You need comprehensive async abstractions |
agnostic-lite |
0.6.0 | Lightweight core (no_std, alloc-free, no unsafe code) | You need minimal abstractions or embedded/no_std support |
agnostic-io |
0.2.0 | Sans-I/O trait definitions | You're building protocol implementations |
agnostic-net |
0.3.0 | TCP/UDP networking abstractions | You need runtime-agnostic networking |
agnostic-dns |
0.3.0 | DNS resolution with DoH, DoT, DoQ, DNSSEC | You need advanced DNS capabilities |
agnostic-process |
0.3.0 | Subprocess spawning and management | You need to spawn external processes |
Use agnostic if:
- You need full-featured async abstractions (networking, DNS, processes)
- You're building applications with multiple async capabilities
- You want a batteries-included experience
Use agnostic-lite if:
- You only need task spawning and time abstractions
- You're working in
no_stdor embedded environments - You want to minimize dependencies
- You're building a library and want minimal footprint
Use individual crates (agnostic-net, agnostic-dns, etc.) if:
- You need specific functionality (e.g., just networking)
- You want fine-grained dependency control
- You're building specialized abstractions
Choose your runtime based on your needs:
- tokio: Mature, widely used, excellent ecosystem
- smol: Lightweight, minimal dependencies
- wasm-bindgen-futures: WebAssembly support
All runtimes work identically with Agnostic abstractions.
- tokio - Enable with
features = ["tokio"] - smol - Enable with
features = ["smol"] - wasm-bindgen-futures - Enable with
features = ["wasm"](agnostic-lite only)
- Unix/Linux: Full support via
rustix - Windows: Full support via
windows-sys - WebAssembly: Supported via
wasm-bindgen-futures(agnostic-lite) - Embedded: Supported via
no_std(agnostic-lite)
agnostic is under the terms of both the MIT license and the
Apache License (Version 2.0).
See LICENSE-APACHE, LICENSE-MIT for details.
Copyright (c) 2024 Al Liu.