libloading

Safe, cross-platform Rust bindings for loading dynamic libraries at runtime

Library
Cargo
v0.9.0
1,466stars
ISC

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
58/100Fair
Development Activity56
Maintenance20
Community56
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
77/100Good
Architecture80
Code Quality82
Innovation74
Learning Curve72

libloading wraps the platform-native dynamic library loading primitives — dlopen/dlsym on Unix and LoadLibrary/GetProcAddress on Windows — behind a single safe Rust API. Its core contribution is memory safety: the crate’s ownership model ties a Symbol’s lifetime to the Library it came from, preventing the classic dangling-pointer bug where code keeps using a function or static pulled from a library that has already been unloaded.

The crate is a foundational building block for plugin systems, FFI bridges, and any Rust program that needs to load shared objects, dylibs, or DLLs discovered at runtime rather than linked at compile time. It compiles conditionally per target family (unix vs windows) and exposes both a cross-platform Library type and lower-level os::unix/os::windows modules for platform-specific control.

What You Get

  • Cross-platform Library type wrapping dlopen (Unix) and LoadLibrary (Windows) with a unified safe API
  • Symbol<T> handles whose lifetime is tied to their owning Library, preventing dangling references after unload
  • Lower-level os::unix and os::windows modules for platform-specific flags and behavior when the cross-platform API isn’t enough
  • no_std-adjacent minimal dependency footprint — only cfg-if on Unix and windows-link on Windows
  • Helpers for constructing platform-correct library filenames (e.g. libfoo.so vs foo.dll)

Common Use Cases

  • Building plugin systems where third-party .so/.dll/.dylib modules are discovered and loaded at runtime
  • Writing FFI bridges to native libraries that are optionally present or version-selected at runtime rather than link time
  • Loading platform-specific system libraries (e.g. graphics or codec libraries) conditionally based on what’s installed
  • Implementing hot-reloadable native extensions or scripting-adjacent native modules

Under The Hood

Architecture — The crate centers on a Library struct (src/lib.rs) that dispatches to os::unix or os::windows (src/os/mod.rs and submodules) via cfg-if based on target family, each wrapping the platform’s native loader (dlopen/dlsym/dlclose or LoadLibraryW/GetProcAddress/FreeLibrary). Symbol<'lib, T> (also src/lib.rs) borrows from its Library with an explicit lifetime parameter, which is the mechanism that prevents symbols from outliving the library they were resolved from. src/util.rs and src/as_filename.rs/src/as_symbol_name.rs provide cross-platform helpers for constructing correctly-formatted library and symbol names. Tech Stack — Minimal-dependency pure Rust, edition 2021, Rust 1.88+. Depends on cfg-if on Unix and windows-link on Windows only; no runtime deps beyond the OS loader itself. A std feature (default-on) gates std-dependent conveniences, keeping a path toward no_std usage. Code Quality — Tests live in a dedicated tests/ integration suite (tests/lib.rs, functions.rs, constants.rs, library_filename.rs, windows.rs, markers.rs) exercising real dynamic-load scenarios per platform, plus a src/test_helpers.rs module and an examples/e1.rs sample. The crate maintains an in-source src/changelog.rs documenting every version’s changes, reflecting unusually disciplined change tracking for a low-level FFI crate. API Design — The public surface is small and intentional: Library::new, .get::<T>(), and the Symbol guard cover the common path in three calls, while os::unix/os::windows expose escape hatches for platform-specific flags (e.g. RTLD_NOW vs RTLD_LAZY) without polluting the default API. The lifetime-based safety guarantee is the standout ergonomic decision — it turns a runtime footgun into a compile-time borrow-check error.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search