Distributing a closed-source Rust library with async - is there a viable path?
Hi r/Rust Redditors,
I'm trying to figure out the best way to distribute a commercial Rust library as a compiled binary rather than source at the request of my employer. The library is heavily async (Tokio).
Here's what I've found so far:
- cdylib + C ABI (.so + .h): Works, stable across compiler versions, but you can't pass Futures or Streams across the boundary. Consumers lose native async integration. Fine for C/C++ consumers, not for Rust ones.
- Pre-compiled .rlib:
- Consumers get native Rust types, async works, but it's pinned to a specific rustc version (no stable ABI).
- Cargo has no native support for rlib dependencies (cargo#1139, open since 2015), so you end up using --extern via .cargo/config.toml which is a hack.
- rust-analyzer doesn't pick up crates declared this way, so no hover docs.
- Standalone types crate + rlib:
- Define the public types and doc comments in a source crate, ship the rlib separately for the actual implementations.
- Consumer gets IDE support from the types crate. But the types in the source crate and the types in the rlib are different types to rustc, so they're incompatible. And orphan rules prevent adding impls across crate boundaries.
- Private registry (ship source): Everything works perfectly - async, IDE, docs. But you're handing over the source. Watermarking + legal terms are the protection, not technical measures.
Has anyone found a better approach? Specifically looking for something where:
- Consumers can .await streams
- IDE hover docs and go-to-definition work
- Implementation source stays closed
Or is "ship source via private registry + legal protection" genuinely the only viable path for async Rust ? If so, I can let them know but thought I'd ask here first in case someone has experience in this area?
Thanks!