atlibs
atlibs runs WebAssembly modules published as atproto records: in a browser page, a Node server, a
Rust server, or the atlibs CLI. A module plans XRPC calls; the host makes them with the user's
session, held to the scope of that module's own OAuth client record.
cargo install --locked --git https://knotless.dev/johnandersen777.bsky.social/atlibs --rev 88b2ba8 atlibs
atlibs add bobvmbuilder.bsky.social/hello
atlibs run hello count '{"did":"did:plc:ocnuqjlzgohypj3zoznermms","collection":"com.fedfork.exec.wasm.module"}'
atlibs new my-module # write one
Docs: use (page, Node, CLI, Rust), write, publish, compose.
Layout
javascript/src/: the JS library, no dependencies (browser and Node hosts, compositions, MCP servers, OAuth helpers); on npm as@publicdomainrelay/atlibsrust/src/abi: the SDK modules are written against;rust/host: the Rust host;rust/cli:atlibs;rust/compose: compositions written in Rustexamples/rust/*: modules;examples/web/*: pages;examples/node-hono: a Node server;examples/rust-host: a Rust program;examples/rust-compose: a composition in Rustrecords/,lexicons/: records to publish, and their schemas
Test
cargo wasm && cargo host && cargo loopback && cargo host-test
node --test examples/rust/*/test.mjs examples/web/*/*.test.mjs examples/node-hono/test.mjs javascript/src/*/*.test.mjs rust/host/*.test.mjs docs/docs.test.mjs
node --import ./rust/host/swap.mjs --test javascript/src/run-module/*.test.mjs examples/rust/*/test.mjs javascript/src/compose/compose.test.mjs javascript/src/server/server.test.mjs javascript/src/mcp/mcp.test.mjs
docs/docs.test.mjs runs every snippet in docs/ (set ATLIBS_DOCS_NETWORK=1 to include the ones
that read the live network). javascript/src/plugin-context/test.html covers the browser engine: serve
the repo root with python3 -m http.server and open it.
Open
-
SSRF: route module calls through the user's PDS, public reads through a relay or AppView, one
hardened DID resolver; drop or allowlist direct
serviceroutes (security) -
Rust host: XRPC, DID resolution and service auth from atproto-crates, once they take a pluggable
fetch (they bring their own reqwest client, which would bypass atlibs'
Fetch) -
Node CLI:
login/logoutwith OAuth on 127.0.0.1, likeatlibs login(today:--app-passwordonly) -
Budget kills skip cleanup: a run stopped by its budget (e.g. a requester
contractpastwallMsafter the accept) gets no chance to release what it holds; give modules a finalclosingevent with a small grace budget, both hosts - Requester (atlibs-socialweb-computer-requester): surface a bidder's rejection reason (e.g. an RFP signed by an unbound badge.blue key) instead of waiting out the budget with "no acceptable bid"
-
Republish the split repos' modules from their own repos so
atlibs verifyreproduces them there - Review / address-review loop until clean