once_cell (Rust)
Safe, ergonomic single-assignment cells and lazy initialization for Rust. once_cell provides OnceCell<T> (single assignment), Lazy<T> (lazy initialization with a closure), and their thread-safe variants (sync::OnceCell, sync::Lazy). Solves the 'global constant that requires computation at startup' problem — global regex, compiled schemas, DB connections — that lazy_static and std::sync::Once handle more verbosely. Most of once_cell's API was stabilized in std (OnceLock, LazyLock) in Rust 1.70+.
Score Breakdown
⚙ Agent Friendliness
🔒 Security
Local library — no network calls. Rust memory safety guarantees. Thread-safe initialization prevents data races.
⚡ Reliability
Best When
You need thread-safe lazy initialization of global constants, singletons, or expensive-to-compute values in Rust agent code — once_cell is the ergonomic solution before std's LazyLock landed.
Avoid When
You're on Rust 1.80+ — use std::sync::LazyLock and OnceLock from the standard library, which graduated from once_cell.
Use Cases
- • Initialize global regex patterns once for agent text processing — lazy static compilation without the lazy_static! macro boilerplate
- • Store application-wide configurations loaded from environment in a global that's initialized once on first access
- • Cache expensive computations in agent services using Lazy<T> — compute once, access many times without explicit locking
- • Implement singleton services (database pools, HTTP clients) in Rust agent code using sync::OnceCell for thread-safe initialization
- • Migrate from lazy_static! macro to std::sync::LazyLock (Rust 1.80+) using once_cell as the transitional API
Not For
- • Mutable shared state — OnceCell is single-assignment; use Mutex<T> or RwLock<T> for mutable shared state across threads
- • Async initialization — OnceCell's init closure runs synchronously; use tokio::sync::OnceCell for async initialization
- • New projects on Rust 1.80+ — use std::sync::LazyLock and std::sync::OnceLock from the standard library instead of once_cell
Interface
Authentication
Local library — no external auth or network calls.
Pricing
MIT/Apache 2.0 dual-licensed open source Rust crate. Note: largely superseded by std equivalents in recent Rust versions.
Agent Metadata
Known Gotchas
- ⚠ If the initialization closure panics, sync::OnceCell is poisoned and subsequent get_or_init() calls will also panic — ensure initialization closures don't panic for global agent resources
- ⚠ unsync::OnceCell is not Send or Sync — it cannot be stored in statics or shared across threads; use sync::OnceCell for shared agent global state
- ⚠ Lazy<T> evaluates the closure on first access, not at program start — agent initialization order cannot be guaranteed if multiple Lazy statics depend on each other
- ⚠ Rust 1.80+ has std::sync::LazyLock and OnceLock — for new agent codebases, prefer the std equivalents to avoid once_cell dependency; the APIs are nearly identical
- ⚠ get_or_try_init() returns a reference to the stored value, not the initialization result — storing errors requires explicitly wrapping in Result<T, E> as the cell value
- ⚠ OnceCell<Mutex<T>> is an anti-pattern — if you need mutable global state, use static Mutex<T> directly; OnceCell adds unnecessary complexity
Full Evaluation Report
Detailed scoring breakdown, competitive positioning, security analysis, and improvement recommendations for once_cell (Rust).
Scores are editorial opinions as of 2026-03-06.