A decentralized, user-programmable execution platform built on the AT Protocol. Each user owns a Box — a compiled WebAssembly binary that is their page. When a visitor hits /@handle, their browser downloads the Box, runs it locally with the owner's data as input, and renders the HTML it returns. The server indexes and distributes; the visitor's device executes.
Canonical data lives in each user's own Personal Data Server (PDS) as signed AT Protocol records — edgeBox is an AppView, not a data silo. Profiles that behave, not just display. Data you own, not data we hold.
- User-owned data. Every post, layout, and link is a signed record in the user's PDS, interoperable with the wider AT Protocol / Bluesky network. edgeBox reads them through an AppView (firehose-populated cache, with a live-fetch fallback) and writes on the user's behalf — it never holds the canonical copy.
- Pages are programs. A Box is real compiled code (Rust →
wasm32-unknown-unknown) executed in the browser's WebAssembly sandbox — no DOM access, no network, no cookies, no cross-user memory reads. The isolation is structural (the Wasm linear-memory model), not policy-enforced. - Edge AI. Boxes can host Actors that run an LLM (Gemma 4 E2B, q4 ONNX) entirely on the visitor's device via WebGPU. No inference server.
- A runtime-native agent. Each viewer has a personal AI agent that follows them across the platform, reads the page they're on as context, and can invoke the tools (Actors) they've equipped — with per-command autonomy governance and prompt-injection defenses.
- P2P distribution. Actors are seeded peer-to-peer over WebRTC DataChannels; every user who installs one becomes a seeder.
Visitor requests /@alice
→ AppView resolves alice's handle → DID → PDS
→ Server sends alice's compiled .wasm Box
→ Browser instantiates it with profile data (signed PDS records, normalized)
→ Box returns HTML
→ Browser renders the page
Boxes run in WebAssembly's linear-memory sandbox with zero imports — no ambient authority. They receive data in and return HTML out; everything else (network, storage, audio, peers, inference) is requested through a versioned, additive-only Host API command surface that the runtime mediates.
edgeBox is an AppView over atproto. The full design is in docs/atproto.md; in brief:
- Lexicons (
lexicons/com/edgebox/*) define the canonical record schemas — profile, box layout, matter (post/track/image/game), follow, actor manifest/publication, and agent permission sets. server/atproto/— handle→DID→PDS resolution, a Jetstream firehose consumer, an indexer that populates the AppView cache, lexicon loading/validation, and PDS writes on the user's behalf.server/appview/— DID-keyed record + profile cache, per-DID compile queue, feed builder, normalizer (atproto records → edgeBox schema), and a live-fetch path for environments without the firehose.- Bluesky interop —
app.bsky.*posts, likes, reposts, and replies are hydrated through Bluesky's public AppView, so an edgeBox feed and a Bluesky feed are the same underlying data.
Prerequisites: Node.js 18+, Rust toolchain (rustup), and wasm-opt (from binaryen).
git clone https://github.com/botBehavior/edgeBox.git
cd edgeBox
npm install
npm start
# → http://localhost:3000To exercise the full atproto path locally, run against a development PDS:
npm run dev-pds:up # start a local PDS (Docker)
npm run dev-pds:seed # create seed accounts + recordsLog in with a handle + app-password (POST /auth/login); the server resolves your PDS and reads/writes records there.
# Rust → wasm32-unknown-unknown → wasm-opt -Os
bash scripts/build_box.sh [box_dir] [output_wasm_path]Visit /@handle/edit to open the DSLBox — a grid-based layout editor (drag-and-drop, snap-to-grid, resize, properties panel). Saving recompiles your layout into a new Box and writes the layout record to your PDS.
| Term | Meaning |
|---|---|
| Box | A compiled .wasm binary — the user's executable page. Contains Views, Micro-Actors, and Actors. |
| Matter | Inert content data (a post, track, image). Travels the network, never executes on the receiver's device. |
| View | A deterministic rendering component. Stateless, fast, no side effects. |
| Actor | A stateful computational entity (AI agent, game, chat). Communicates via commands — zero Wasm imports. |
| Host API | The JSON contract passed into every Box at render time. Versioned, additive-only — the platform's capability surface. |
Actors are self-contained Wasm modules with an init/update/render lifecycle, the same zero-import sandbox as Boxes. They express intent through commands (audio.*, matter.*, peer.*, inference.*, agent.*, …) that the runtime mediates.
Inference-capable Actors request generation via the inference.* namespace; the runtime loads Gemma 4 E2B (q4 ONNX) into a Web Worker and runs it on-device via WebGPU. A mock mode echoes input when WebGPU is unavailable, so the full pipeline is testable without a GPU.
The runtime agent is a viewer-scoped service (not a per-page actor): it lives in the shared inference worker, persists to IndexedDB across navigation, reads the current page as context, and invokes equipped vs. page tools through a namespaced CALL protocol with two-axis autonomy governance (source × owner). Authored page context is treated as data, never instructions — a deliberate prompt-injection boundary.
boxes/ Rust source for Boxes and Actors
sdk/ Box ABI (alloc/render/dealloc) + rich-rendering helpers
actor-sdk/ Actor ABI (init/update/render)
actors/ Built-in actors (incl. the runtime agent)
dslbox/ Visual layout editor
feedbox/ marketplacebox/
runner/ JavaScript runtimes (browser + Node + Deno), SPA shell, inference worker/bridge
server/ Zero-dependency Node.js HTTP server (SSR, auth, routing)
atproto/ PDS client, jetstream, indexer, lexicon loader, writes
appview/ cache, feed, normalize, compile queue, live-fetch
lexicons/com/edgebox/ Canonical AT Protocol record schemas
host-api/ Versioned Host API schema (additive-only)
scripts/ Build, test, dev-PDS tooling
Every Box exports exactly three functions: alloc(len) -> ptr, render(ptr, len) -> packed(out_ptr<<32 | out_len), and dealloc(ptr, len). Box authors write only render_page(input) -> Output — pure logic, no I/O. The SDK handles the rest.
- Boxes/Actors: Rust →
wasm32-unknown-unknown→wasm-opt -Os(no WASI, no imports) - Runtime: Node.js ESM, zero runtime dependencies beyond
@atproto/api - Server: zero-dep
node:httpSSR - Inference:
@huggingface/transformers+ ONNX Runtime Web + WebGPU, CDN-loaded, isolated in a Web Worker - Data: AT Protocol records in the user's PDS; serde with
rename_all = "camelCase"
npm run test:unit # 220 unit tests (Node-only, fetch-stubbed, ~1s)
npm test # full suite incl. the wasm build pipelineCoverage spans the build pipeline, XSS/SSR, auth + OAuth, the agent framework, the atproto client/jetstream/indexer, and every AppView module.