Crabrix blog

Crabrix SDK: share a Rust Playground from JavaScript, Rust and Go

Integrate temporary Rust workspaces into agents with the crabrix npm library, Rust and Go bindings, exact revisions and permission-gated local Run/Debug.

A shared work surface is smaller than a repository

An agent often needs somewhere to show a small Rust example, ask for review and preserve another participant’s edits. Creating an entire repository can be unnecessary for that conversation. A temporary work surface has a different contract: a few source files, a clear deadline, live selections and a link that another participant can open immediately. Durable history and access management still belong in the project’s ordinary version-control system.

The standalone crabrix package provides that work surface as both a JavaScript/TypeScript library and an MCP server. It can create an encrypted temporary Playground, inspect its source, make a revision-checked change and hand the room to another agent. Nobody needs the iPhone app to use this workflow. The web editor can display the same source, and the app remains an optional companion when its native project tools are useful.

The distinction matters when designing an integration. Do not present a successful room creation as a repository push, a saved account project or a permanent published application. Present it as a temporary Playground with an expiry. A good agent interface can show the room’s name, deadline and access mode next to its explicit share action, while keeping the complete secret capability out of routine logs.

Crabrix crab connecting JavaScript, Rust and Go cards to one temporary workspace
Conceptual SDK illustration. Rust and Go bindings use the common local JavaScript protocol core; they are not independent Rust compilers.

Explore in Crabrix: SDK and MCP setup · Try a browser Playground

Use one protocol core across three language APIs

The JavaScript implementation supplies the shared protocol core. The Rust and Go libraries embed that same local bridge and communicate with it over bounded stdio. All three require Node.js 22 or newer. This is an intentional implementation boundary: the Rust and Go packages provide language-appropriate APIs and process ownership, rather than pretending to offer separately implemented cryptographic stacks or native on-host Rust compilation.

The bindings do not need a global npm installation because the bridge is included with them. Their local process handles room encryption, collaborative document updates, selections and signed runtime messages. It does not expose a shell tool or an API for reading arbitrary host files. A language binding can therefore share the same edit and permission rules without inventing its own interpretation of a room capability.

For maintainers, a common core also makes evidence easier to compare. The embedded bridge bytes can be checked against the release manifest, and the same browser can participate in a room opened by any binding. That does not eliminate bugs in process management or language APIs, so those transports still need their own tests. In this release, the public browser and JavaScript, Rust and Go clients were checked together rather than relying only on disconnected unit tests.

Three SDKs using a local Node protocol core, encrypted relay and explicitly permitted browser or app execution
All SDK variants require Node.js 22+. The relay stores temporary ciphertext and never compiles or executes Rust.

Sources: MCP stdio transport

Integrate directly into a JavaScript agent

Install crabrix when you want to call a library from your own program. ESM, CommonJS and TypeScript declarations are included. The npm release is bundled without runtime npm dependencies or installation hooks. That describes the SDK distribution; it does not mean live collaboration works without a network connection, and it does not include an AI model subscription, provider credential or browser compiler download.

Create one client per room and give it a useful participant name. The name is visible to collaborators and is a label, not identity verification. A structured source snapshot contains validated text and a revision; status exposes file paths, byte counts, expiry, participants and selections without returning a secret link. Requesting a share link is a separate, explicit operation, which keeps access out of routine status polling.

The following example makes a small source change and obtains an intended handoff. The surrounding application must decide where to deliver the secret link. It deliberately does not log it. Closing the client leaves other participants and the room available until their existing deadline; if the creator wants to close the room for everyone, it must invoke the separate end-room operation before disconnecting.

import { Crabrix } from "crabrix";

const agent = new Crabrix({ name: "Review agent" });
try {
  await agent.create({
    name: "Small Rust example",
    lifetimeMinutes: 60,
    files: { "main.rs": 'fn main() { println!("hello"); }
' },
  });
  const file = await agent.read("main.rs");
  await agent.apply({
    expectedRevision: file.revision,
    changes: [{
      path: file.path,
      text: file.text.replace("hello", "hello from an agent"),
    }],
  });
  const handoff = await agent.share("edit");
  // Deliver handoff.link only to an intended participant.
  // Display handoff.expiresAt next to your explicit share action.
} finally {
  agent.close();
}

Sources: Crabrix npm package · Public SDK source

Use the Rust binding with explicit process ownership

The Rust binding exposes a client that owns its local bridge process. Its typed options cover room creation, file changes, selections and handoff results. Source fields and capability links are not placed in process arguments. Normal debug formatting of a handoff redacts its link, although an application can still expose the field deliberately when the user requests sharing. Callers should keep that distinction in their own logging and telemetry.

The Rust library is published as crabrix version 0.3.0 on crates.io. Add it to a project with cargo add crabrix@0.3.0, or install the optional MCP executable with cargo install crabrix --version 0.3.0 --locked. The registry archive checksum matches the prepared release, and a fresh registry installation reports the expected version. Node.js 22 or newer remains a prerequisite because the crate embeds the common JavaScript protocol core.

The code below shows the library’s shape. A successful start of the bridge only establishes a local protocol connection. Creating a room performs the separate encrypted sharing operation. For an existing room, use its authorized complete link instead. Dropping the client releases its own bridge; ending a room for all participants is an explicit creator action. Do not silently reconstruct a client and replay a possibly committed edit after a timeout.

use crabrix::{ApplyOptions, Change, Client, CreateOptions};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = Client::new()?;
    client.create(&CreateOptions::new("Rust agent example"))?;
    let file = client.read("main.rs")?;
    client.apply(&ApplyOptions {
        expected_revision: file.revision,
        changes: vec![Change {
            path: file.path,
            text: Some(file.text + "// reviewed in Rust
"),
        }],
        entry_file: None,
        name: None,
    })?;
    let handoff = client.share("edit")?;
    assert_eq!(handoff.mode, "edit");
    Ok(())
}

Sources: Crabrix Rust package on crates.io · Cargo publishing process · Crabrix Rust API documentation

Use the Go binding with a meaningful context

The Go module provides corresponding creation, source, edit, selection and runtime methods. Use a context that represents the integration’s lifetime, then close the client when the room interaction is finished. A canceled request should not become an excuse for blindly repeating a write. The transport reports cancellation and ambiguous outcomes so the caller can reconcile the actual room state before deciding what to do next.

The source module lives under the public SDK repository’s Go path. A tagged module version identifies immutable source for Go tooling; it is not a separate centrally reserved package name. The installed executable can be named crabrix, while imports use the complete module path. Node.js 22 or newer is still required because this binding embeds the shared JavaScript bridge rather than a different room implementation.

When integrating into a long-running agent, distinguish its normal request context from a process-wide shutdown. Avoid passing a context that is already canceled, and give each operation a bounded lifetime. The SDK caps transport frames and queues; your application should also avoid creating a new room for every token or launching an unbounded number of clients. One deliberate shared workspace is usually more useful than many anonymous temporary connections.

package main

import (
    "context"
    "github.com/sergii-ziborov/crabrix-sdk/go/crabrix"
)

func main() {
    ctx := context.Background()
    client, err := crabrix.New(ctx, crabrix.Options{})
    if err != nil { panic(err) }
    defer client.Close()
    _, err = client.Create(ctx, crabrix.CreateOptions{Name: "Go agent example"})
    if err != nil { panic(err) }
    file, err := client.Read(ctx, "main.rs")
    if err != nil { panic(err) }
    updated := file.Text + "// reviewed in Go
"
    _, err = client.Apply(ctx, crabrix.ApplyOptions{
        ExpectedRevision: file.Revision,
        Changes: []crabrix.Change{{Path: file.Path, Text: &updated}},
    })
    if err != nil { panic(err) }
}

Sources: Go SDK source · Publishing Go modules

Treat handoff as an access decision

A handoff includes a link, its access mode, expiry and current revision. That is enough for another authorized agent to join the same work surface without an application-specific account. It is also enough to grant the link’s permitted source access, so keep it out of public issues, generated code comments and routine diagnostics. Passing a link between agents is an explicit action, not an incidental side effect of asking for status.

The creator retains a separate view capability and can request a view handoff. A participant that merely joined with an edit link does not possess that separate capability, so it cannot manufacture a weaker link by changing a display field. Similarly, a view participant cannot escalate to editing. These details matter when one agent is allowed to review but another is expected to make the requested change.

A useful handoff message describes the task, the last inspected revision, the deadline and what was actually verified. The link itself can travel through the recipient’s authorized private channel. Avoid implying that a revision is permanent repository history: another participant may edit the room immediately afterward. The receiving agent should read current status and relevant source before proposing its own change.

Explore in Crabrix: Shared interview workflow · Sharing guide

Reject stale replacements and reconcile uncertain outcomes

The source revision is a content identity, while the relay’s sequence identifies the update order. A conditional edit checks its expected base before committing encrypted change data. This protects against replacing a human’s or another agent’s intervening work. It does not mean concurrent participants are unable to edit; it means an agent’s proposed replacement must be reconsidered when its basis is no longer current.

Read the relevant files, build one bounded proposal and apply it with the returned revision. When a conflict occurs, inspect the newer source. Sometimes the correct response is to merge the requested change; sometimes another participant has already made it unnecessary. Do not create a loop that fetches a new revision and resends the exact old replacement unchanged. That would turn a useful guard into a decorative extra request.

A lost HTTP acknowledgement is different from a known rejection. The shared core uses a stable message identifier and ciphertext for a safe retry of the same conditional commit. If the final outcome remains uncertain, it asks the caller to read state before deciding on a new action. The language transports likewise avoid claiming success from a disconnected response stream. This is a practical reliability contract, not a promise that networks never fail.

Revision-checked edit flow with accepted and conflicting branches
A stale proposal is rejected. The agent must read and reconcile the newer source before preparing another edit.

Explore in Crabrix: Explicit state machines in Rust

Keep execution authority separate from source access

A room edit link does not grant permission to execute code on someone else’s client. An agent first discovers signed runtime capabilities, selects a target fingerprint and requests particular operations. A human compares the full controller and client keys in Share and allows the selected operations on that specific browser or app. The grant is short lived and can be revoked; a participant name alone is not identity verification.

Use the runtime source revision returned by discovery when starting an allowed operation. The start result identifies an owned job, not a successful program. Poll that job’s actual state, then inspect its diagnostics or paged output. Build does not execute main. Debug exposes bounded real locals, stepping and owned Stop; it does not evaluate arbitrary host expressions. Shared jobs have their own deadline, including pauses, and a source change stops stale work.

Other participants may receive a reported output preview, but receiving that preview never starts their compiler or debugger. It is display data, not trusted evidence about their own full project or learning progress. The browser or app that executes retains the full owned result within its limits. The relay carries encrypted messages only. It has no Rust execution backend, shell interface or access to a participant’s private local project inputs.

Explore in Crabrix: Local runtime and debugger guide · Platform and execution boundaries

Design cleanup and expiry into your integration

Room source is capped at 16 supported text files, 64 KiB per file and 128 KiB in total. Package archives, images, compiler caches, credentials and private configuration are outside the shared document. Keep larger project machinery in its original environment and extract a small reproducible source example when that is what collaborators need. A small workspace with an honest boundary is easier to inspect than a partially imported project presented as complete.

The default room lifetime is one hour, with a maximum of 24 hours. The relay holds bounded ciphertext in process memory, without a permanent account project, database source record or backup. A restart can end a room before its advertised expiry. Your integration should display the deadline and offer a clear path to an ordinary local source copy. Rejoining is not a keepalive mechanism for extending the original lifetime.

Close clients and unused tabs when they are no longer participants. Keep creator-only room closure separate from a single participant leaving. If a user presses Stop, do not quietly choose another runtime and start the same program again. Cancellation and loss of permission are meaningful state changes. An agent that explains them clearly is more dependable than one that hides them behind an unlimited retry policy.

Explore in Crabrix: Project recovery and export · Typed data boundaries

Pin real releases and inspect the evidence

Use a pinned package version in a reproducible MCP configuration, and use normal semantic versioning when updating the SDK in an application. The public repository contains the JavaScript source, Rust and Go bindings, license notices and qualification records. The brand images and real app screenshots make the project recognizable, but they are not evidence that a specific code path ran. Look for the actual test and release results.

The release was checked with an official MCP client, an actual browser compiler and a four-participant room containing JavaScript, Rust, Go and the browser. Source edits, Unicode, named selections and stale-revision rejection were observed. Build, Run, structured Debug locals, stepping and Stop were checked separately in the browser. The language bindings also have their own transport tests. These checks describe those exact profiles; they do not claim that every arbitrary Rust repository can run in the web Playground.

For durable work, take the reviewed source back to your own repository and normal review process. Crabrix provides a small shared place to explain, edit, test and hand off that source. It does not replace Git hosting, a production runtime or an organization’s access system. Keeping that purpose clear makes the SDK useful to ordinary agents as well as people using the Crabrix app, and leaves a straightforward path for improving it through public, testable releases.

Sources: SDK source and qualification records · npm release

Explore in Crabrix: All Rust courses · Full Crabrix guide

Explore the free Crabrix lessons →