Crate native_messaging

Crate native_messaging 

Source
Expand description

§Native Messaging — Async Rust host + manifest installer

This crate helps you build a Native Messaging host for WebExtensions and install/manage the host manifest for multiple browsers across platforms.

It exposes two main areas:

  • host — encode/read/write native-messaging frames over stdin/stdout, plus an async event_loop for handling messages.
  • install — create host manifests, verify their presence, and remove them for supported browsers.

The installer side is config-driven via an embedded browsers.toml. The embedded config includes the following browser keys (as of this release):
"chrome", "edge", "chromium", "brave", "vivaldi", "firefox", "librewolf".

§Encode a JSON message into a native-messaging frame

use native_messaging::encode_message;
use serde::Serialize;

#[derive(Serialize)]
struct Msg {
    hello: &'static str,
}

// Encode to a 4-byte-length-prefixed frame:
let frame = encode_message(&Msg { hello: "world" }).unwrap();
assert!(frame.len() >= 4);

§Read one message and reply (async)

use native_messaging::{get_message, send_message};
use serde::{Deserialize, Serialize};

#[derive(Deserialize)]
struct In { ping: String }

#[derive(Serialize)]
struct Out { pong: String }

let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
    // Incoming messages are framed and decoded as a raw JSON string:
    let raw = get_message().await.unwrap();

    // Parse to your input type:
    let incoming: In = serde_json::from_str(&raw).unwrap();

    // Build and send a reply:
    let reply = Out { pong: incoming.ping };
    send_message(&reply).await.unwrap();
});

§Run the event loop

use native_messaging::{event_loop, send_message};
use serde::Serialize;
use std::io;

#[derive(Serialize)]
struct Out { pong: String }

let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
    event_loop(|msg: String| async move {
        // In real code, you'd parse `msg` into a structured type first.
        let reply = Out { pong: msg };
        send_message(&reply).await?;
        Ok::<(), io::Error>(())
    })
    .await;
});

§Install a manifest (config-driven browsers)

Browsers are selected by string keys from the embedded browsers.toml.

  • allowed_origins is used for Chromium-family browsers (chrome, edge, chromium, brave, vivaldi).
  • allowed_extensions is used for Firefox-family browsers (firefox, librewolf).
use std::path::Path;
use native_messaging::install::{install, Scope};

let host_name = "com.example.host";
let description = "Example native messaging host";

// IMPORTANT: On macOS/Linux, this must be an absolute path.
let exe_path = Path::new("/absolute/path/to/host-binary");

// Chromium-family allow-list:
let allowed_origins: Vec<String> = vec![
    "chrome-extension://your_ext_id/".to_string(),
];

// Firefox-family allow-list:
let allowed_extensions: Vec<String> = vec![
    "your-addon@example.org".to_string(),
];

// Pick which browsers to install for (keys from browsers.toml):
let browsers = &["chrome", "firefox", "edge"];

install(
    host_name,
    description,
    exe_path,
    &allowed_origins,
    &allowed_extensions,
    browsers,
    Scope::User,
).unwrap();

§Verify installation

On Windows, verification is registry-aware for browsers that require registry pointers; on macOS/Linux, verification checks the expected manifest file path.

use native_messaging::install::{verify_installed, Scope};

let host_name = "com.example.host";

// Verify for all configured browsers (pass None) in user scope:
let ok = verify_installed(host_name, None, Scope::User).unwrap();
assert!(ok);

§Remove a manifest

use native_messaging::install::{remove, Scope};

let host_name = "com.example.host";
let browsers = &["chrome", "firefox", "edge"];

remove(host_name, browsers, Scope::User).unwrap();

Modules§

host
install
manifest
paths

Enums§

Scope

Functions§

encode_message
Encode any serde-serializable value into the native-messaging frame: 4-byte native-endian length + JSON bytes.
event_loop
get_message
install
Install manifests for the given browser keys (from browsers.toml).
remove
Remove manifests + registry keys for the given browser keys.
send_message
verify_installed
Verify installation for a host across browsers.