9 releases (4 breaking)
Uses new Rust 2024
| new 0.10.0 | Feb 14, 2026 |
|---|---|
| 0.9.1 | Feb 7, 2026 |
| 0.8.1 | Feb 5, 2026 |
| 0.7.0 | Jan 31, 2026 |
| 0.6.2 | Jan 30, 2026 |
#95 in FFI
190KB
3K
SLoC
rustbridge
[!NOTE] Approaching 1.0 — Core components (bundle format, JSON transport, language bindings) should be stable. It's not yet published to package registries (e.g. Maven Central, NuGet, PyPI), so rustbridge consumer libraries must be installed from source.
rustbridge lets you write shared library plugins in Rust that can be called from Java, Kotlin, C#, Python, Go, Erlang, or another version of Rust — without dealing with the C ABI directly.
The Problem
flowchart LR
subgraph chasm["🕳️ The C ABI Chasm"]
direction TB
ub["Undefined Behavior"]
seg["Segfaults"]
ptr["Raw Pointers"]
align["Memory Alignment"]
leak["Memory Leaks"]
types["Primitive C Types"]
style chasm fill: #1a1a1a, stroke: #ff4444, color: #ff6666
end
Calling Rust from other languages typically means writing C bindings. That means dealing with:
- Undefined behavior from incorrect memory handling
- Segfaults from null pointers or use-after-free
- Memory leaks from forgotten deallocations
- Type mismatches between languages
- No error handling (C has no exceptions or Result types)
- Manual serialization of complex data structures
One of your goals may be to work exclusively in memory safe languages, but in order to get from one language to the other, you'll need to cross the C ABI Chasm.
A Solution
With rustbridge, you can write a plugin once, and call it from various languages without needing to cross the C ABI chasm directly:
flowchart LR
subgraph safe_rust["🦀 Rust"]
plugin["Your Plugin<br/><code>impl Plugin</code>"]
end
subgraph crossing[" "]
direction TB
bridge["🌉 rustbridge"]
chasm["🕳️ C ABI"]
end
subgraph safe_host["☕ Host Language"]
java["Java / Kotlin"]
csharp["C#"]
python["Python"]
end
plugin -- " .rbp bundle " --> bridge
bridge --> java
bridge --> csharp
bridge --> python
style chasm fill: #1a1a1a, stroke:#ff4444, color: #ff6666
style bridge fill:#22aa22, stroke: #44ff44, color: #ffffff
style crossing fill: none, stroke: none
style safe_rust fill: #f5a623, stroke: #ff8c00,color: #000000
style safe_host fill: #4a90d9,stroke: #2e6cb5, color: #ffffff
rustbridge handles the messy bits. You get:
- High-level JSON, native Rust speed — Work with serde types, not raw pointers
- Stable C ABI — Plugins work regardless of your Rust compiler version or optimization flags
- One plugin, many languages — Same binary called from Java, Kotlin, C#, Python, Go, or Erlang
- Production-ready bundles — Code signing, SBOM, checksums, multi-platform support
- Managed lifecycle — Startup, shutdown, and logging callbacks built-in
Project Status
Components planned for a 1.0 release:
| Component | Status |
|---|---|
| JSON Transport | Stable |
| Plugin Lifecycle | Stable |
| Bundle Format | Stable |
| Java FFM Bindings | Stable |
| C# Bindings | Stable |
| Python Bindings | Stable |
| Binary Transport | Stable |
| Documentation | In-progress |
The .rbp Bundle
Plugins ship as .rbp bundles (portable ZIP files containing at a minimum: a manifest and one or more shared
libraries).
An .rbp bundle may also include:
| Feature | Description |
|---|---|
| Multi-platform | Linux, macOS, Windows (x64 + ARM64) may be bundled in one file |
| Code signing | Minisign signatures for authenticity verification |
| SBOM | CycloneDX and SPDX for supply chain transparency |
| Variants | Release + debug builds, custom feature flags |
| Checksums | SHA256 verification of all binaries |
| Provenance | Git commit, CI job, build timestamp tracking |
Create a bundle from your plugin directory:
rustbridge pack
Or use rustbridge bundle create for multi-platform bundles:
rustbridge bundle create \
--name my-plugin --version 1.0.0 \
--lib linux-x86_64:target/release/libmyplugin.so \
--lib darwin-aarch64:target/release/libmyplugin.dylib \
--lib windows-x86_64:target/release/myplugin.dll \
--output my-plugin-1.0.0.rbp
Load from any language; rustbridge will auto-detect the platform:
Plugin plugin = BundleLoader.load("my-plugin-1.0.0.rbp");
Quick Example
Rust plugin:
use rustbridge::prelude::*;
#[derive(Default)]
pub struct EchoPlugin;
#[async_trait]
impl Plugin for EchoPlugin {
async fn handle_request(&self, _ctx: &PluginContext, type_tag: &str, payload: &[u8]) -> PluginResult<Vec<u8>> {
match type_tag {
"echo" => Ok(payload.to_vec()), // Echo back the input
_ => Err(PluginError::UnknownMessageType(type_tag.to_string())),
}
}
}
rustbridge_entry!(EchoPlugin::default);
Java consumer:
try (Plugin plugin = FfmPluginLoader.load("libecho.so")) {
String response = plugin.call("echo", "{\"message\": \"Hello!\"}");
System.out.println(response); // {"message": "Hello!"}
}
Get Started
The fastest way to understand rustbridge is to build something:
📖 Getting Started Guide — Create your first plugin and call it from Java
Language Guides
| Language | Version | Guide |
|---|---|---|
| Java | 21+ | docs/using-plugins/JAVA_FFM.md |
| Kotlin | 2.0+ | docs/using-plugins/KOTLIN.md |
| C# | .NET 8.0+ | docs/using-plugins/CSHARP.md |
| Python | 3.10+ | docs/using-plugins/PYTHON.md |
| Rust | 1.90+ | docs/using-plugins/RUST.md |
| Go | 1.21+ | docs/using-plugins/GO.md (Tier 2) |
| Erlang | OTP 27+ | docs/using-plugins/ERLANG.md (Tier 2) |
Note: Java 21 users must add
--enable-previewflag. It works, but Java 22+ is recommended. Note: Rust consumers must be created as separate projects withcargo newto avoid workspace conflicts. Note: Go and Erlang are Tier 2 — expected to work, tested on Linux, but not all OS permutations validated. See Architecture for tier definitions.
Install from Source
rustbridge is not yet published to package registries. Install from source to get started.
📖 Full Installation Guide — Set up your workspace, install the CLI, and configure host language libraries.
Quick start:
# 1. Set up workspace (add to ~/.bashrc or ~/.zshrc)
export RUSTBRIDGE_WORKSPACE="$HOME/rustbridge-workspace"
mkdir -p $RUSTBRIDGE_WORKSPACE
# 2. Clone and install CLI
cd $RUSTBRIDGE_WORKSPACE
git clone https://github.com/jrobhoward/rustbridge.git
cd rustbridge
cargo install --force --path crates/rustbridge-cli
# 3. Verify
rustbridge --version
See the full guide for host language library setup (Java/Kotlin, C#, Python).
Contributing
We welcome contributions! See CONTRIBUTING.md for guidelines.
Quick start:
- Check docs/TASKS.md for open tasks
- Read docs/SKILLS.md for coding conventions
- Read docs/TESTING.md for testing guidelines
Technical Documentation
For those who want to understand the internals:
- Architecture — System design and component overview
- Bundle Format — .rbp specification
- Transport Layer — JSON and binary protocols
- Memory Model — Ownership patterns across FFI
- Error Handling — Error codes and patterns
- Plugin Lifecycle — State machine details
Changelog
See CHANGELOG.md for version history.
License
MIT OR Apache-2.0
Attribution
This project includes software licensed under the Unicode License. See NOTICES for details.
Dependencies
~12–17MB
~222K SLoC