inventory
Typed distributed plugin registration for Rust with no central list required
Repository Health
Technical Analysis
inventory provides a way to set up a plugin registry that any source file linked into a Rust application can contribute to, without maintaining a single central list of registrations. A crate declares a plugin type once with inventory::collect!(Type), and then any crate — the declaring crate itself or any downstream dependent — can register instances with inventory::submit! { ... } from anywhere in its source, with all submissions across the whole binary becoming visible via inventory::iter::<Type> before main even runs.
This solves the same problem as tools like gflags’ distributed flag registration: a central list of registrations becomes a merge-conflict bottleneck once many contributors are adding to it independently. Under the hood, inventory relies on life-before-main constructor functions (similar to C’s __attribute__((constructor)) or the ctor crate) that run at program startup and dynamic-library load time, building a lock-free linked list per plugin type using atomic compare-exchange operations. It supports Linux, macOS, iOS, FreeBSD, Android, Windows, WebAssembly, and other platforms, with graceful degradation (no plugins found) elsewhere.
What You Get
inventory::collect!(Type)to declare a plugin registry for a type, called once in the crate that defines itinventory::submit! { ... }to register a plugin instance from any crate with access to the type, at any point in the sourceinventory::iter::<T>as a'static-lifetime iterator over every registered instance of typeT, ready to use at the start ofmain- Constructor-based registration (life-before-main) that works across dynamically loaded libraries too, registering at
dlopentime no_stdsupport and WebAssembly compatibility, including guidance for ensuring constructors run correctly in Wasm’s command-style linkage model
Common Use Cases
- Building a command-line flags library where any source file in a large application can register its own relevant flags
- Implementing a plugin system where downstream crates contribute handlers, extensions, or test cases without editing a shared registry file
- Collecting distributed test cases, benchmarks, or schema definitions scattered across many source files into one iterable collection
- Avoiding merge-conflict-prone central registration lists in large, multi-contributor Rust codebases
Under The Hood
Architecture - Each collect!(Type) call generates a static REGISTRY: Registry holding an AtomicPtr<Node> used as the head of a lock-free singly linked list. Each submit! invocation expands (via the __do_submit! macro) into a static Node plus a platform-specific constructor function placed in a linker section that runs at program startup — .init_array on ELF platforms, __DATA,__mod_init_func on macOS/iOS, .CRT$XCU on Windows, with WebAssembly handled specially via __wasm_call_ctors and an initialized atomic-bool guard to prevent double-registration under Wasm’s fragile command-style-linkage heuristic. Registration itself uses compare_exchange-based CAS loops to prepend nodes to the list safely even if multiple constructors race (relevant for statically-linked large binaries). inventory::iter::<T> is implemented via a Deref-based zero-sized-type trick (credited to the ghost crate pattern) that lets a type alias double as both a type and a callable iterator constructor.
Tech Stack - #![no_std] pure Rust with zero mandatory dependencies; rustversion is pulled in only as a WebAssembly-target dependency to handle version-gated link_section attribute support across Rust toolchain versions. trybuild is used as a dev-dependency for macro-expansion/compile-fail testing.
Code Quality - tests/test.rs exercises multi-type registration and iteration correctness, while tests/compiletest.rs (via trybuild) verifies that misuse patterns — like calling submit! from inside a function body — fail to compile with a clear diagnostic, which is essential given how much of this crate’s correctness depends on macro-generated code that user mistakes could silently break. The crate documents unsafe invariants inline (e.g. SAFETY: requires *node.value is of type Self) at every unsafe block, and the WebAssembly-specific double-initialization guard shows the maintainer actively tracking edge cases in linker behavior across platforms, not just the common case.
API Design - The three-macro surface (collect!, submit!, iter::<T>) requires almost no boilerplate — plugin authors just write a submit! block anywhere in their crate, with no wiring back to a central file. The crate-level docs are unusually explicit about footguns (don’t call submit! inside a function body; iteration order is unspecified) and back that up with compile_fail doctests, reducing the risk of confused first-time usage of a fairly unusual (constructor-based) registration mechanism.
Used by 4 apps in this directory
Cap
Team Chat · Video Conferencing
Open source Loom alternative with GPU-accelerated recording, instant share links, AI summaries, and full self-hosting via Docker Compose.
helix-db
Databases
A graph-vector database built from scratch in Rust that unifies graph traversal, vector search, key-value, and relational storage into a single platform for AI applications.
iii
Developer Tools · Devops
Compose, extend, and observe every backend service in real time using three primitives: Workers, Functions, and Triggers.
Spacedrive
File Storage · Collaboration
One file manager for all your devices and clouds — powered by a Virtual Distributed File System built in Rust.