rustbridge-runtime 0.9.0

Tokio async runtime integration for rustbridge
Documentation

rustbridge

CI License Rust Java .NET Python

[!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, 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#, or Python
  • 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

Note: Java 21 users must add --enable-preview flag. It works, but Java 22+ is recommended. Note: Rust consumers must be created as separate projects with cargo new to avoid workspace conflicts.

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:

  1. Check docs/TASKS.md for open tasks
  2. Read docs/SKILLS.md for coding conventions
  3. Read docs/TESTING.md for testing guidelines

Technical Documentation

For those who want to understand the internals:

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.