Overview

Architecture

How OXP is structured: the monorepo, the package graph, the WASI runtime, and how everything fits together.

OXP is organized as a pnpm monorepo with a clear separation between the spec, the runtime packages, the CLI, the registry web app, and the host adapters. This page walks through the architecture top-to-bottom.

Monorepo Layout

oxp/
├── spec/v1/              Normative specification (schema, protocol, bundle format)
├── packages/
│   ├── types/            TypeScript types for manifest + protocol (source of truth)
│   ├── schema/           JSON Schema + Ajv validator for oxp.json
│   ├── bundle/           Pack, unpack, sign, verify .oxp bundles
│   ├── sdk/              Author-facing SDK (defineExtension, HostApi, capability helpers)
│   ├── ui/               @oxprotocol/ui component vocabulary + DOM renderer
│   ├── cli/              The `oxp` command-line tool
│   ├── create-oxp/       `npm create oxp` wrapper (reserved, delegates to CLI)
│   ├── host-core/        Runtime-agnostic install + verify + activate pipeline
│   ├── host-runtime/     WASI Component Model runtime (jco backend, capability broker)
│   └── wit/              WIT contracts (oxp:host + oxp:extension worlds)
├── hosts/
│   ├── vscode/           VS Code / Cursor / Windsurf / VSCodium host adapter
│   ├── jetbrains/        IntelliJ Platform host adapter (Kotlin)
│   ├── neovim/           Neovim host adapter (Lua)
│   └── piye/             Piye IDE native L2 host adapter (in progress)
├── apps/
│   └── web/              Registry website + API (Next.js + Prisma + Postgres)
├── examples/
│   ├── hello-world/      HTML template extension
│   ├── hello-rust/       Rust WASI component extension
│   └── security-tests/   Malicious bundle fixtures for security testing
└── docker-compose.yml    Local Postgres + MinIO for development

Package Dependency Graph

The packages form a clean dependency tree with @oxprotocol/types at the root:

types ─────────┬──── schema
               ├──── sdk
               ├──── ui
               ├──── wit ──────── host-runtime
               │                      │
               ├──── bundle ──────────┤
               │                      │
               └──── host-core ───────┘
                         │
                     cli ┘

Every package is published to npm under the @oxprotocol scope. The workspace:* protocol is used for internal dependencies during development.

The WASI Component Model

OXP extensions run as WASI Preview 2 components. This is not optional — it is the foundation of OXP's security model.

Why WASI

PropertyTraditional (Worker threads)WASI Component Model
IsolationRealm-only; shared OS processSFI; capabilities are linker-level imports
UniversalityJS only; per-OS binariesOne .wasm runs on every OS / CPU / host
LanguagesJS / TSRust, Go, C/C++, Python, JS (via jco)
StandardizationAd-hocBytecode Alliance standard
Capability modelRuntime checksType system (WIT imports)
Audit story"Trust our gate code""Diff the import list"

Runtime Topology

The WIT contract is identical on both backends — that is the entire point.

┌────────────────────── Host ──────────────────────┐
│  @oxprotocol/host-runtime                        │
│  ┌──────────────────┬────────────────────────┐   │
│  │ NODE / DESKTOP   │ BROWSER / WEBVIEW      │   │
│  │ wasmtime or      │ native WebAssembly     │   │
│  │ jco shim         │ + jco-transpiled shim  │   │
│  └────────┬─────────┴──────────┬─────────────┘   │
│           │  WIT host-funcs    │                  │
│           ▼  (broker)          ▼                  │
│  ┌────────────────────────────────────────────┐   │
│  │ Extension component (.wasm)                │   │
│  │  imports: oxp:host/ui, oxp:host/fs, …      │   │
│  │  exports: lifecycle, ui-handler, …         │   │
│  └────────────────────────────────────────────┘   │
└──────────────────────────────────────────────────┘

Bundle Kinds

Every OXP bundle has a kind that drives security policy:

KindDescriptionCode Allowed
ui-v1Declarative JSON tree only. No executable code.❌ No JS/TS/Wasm
component-v1Ships a WASI component. Must declare a WIT pin.✅ Wasm only
hybrid-v1Both a UI tree and a Wasm component.✅ Wasm only

Existing bundles published before the kind field default to ui-v1 on read — backward compatible.

WIT Contracts

The packages/wit/ package is the most important package in the repo. It contains the WIT (WebAssembly Interface Types) contracts that define the interface between host and extension:

  • **oxp:host@0.1.0** — capabilities the host provides: log, storage, ui, fs, net, secrets, commands
  • **oxp:extension@0.1.0** — interfaces extensions export: lifecycle, ui-handler, command-handler

The install prompt reads the component's import list at install time. The binary cannot import what the manifest did not declare, because the registry validates manifest.permissions ⊇ component.imports on upload.

The Capability Broker

The CapabilityBroker in packages/host-runtime/src/broker.ts mediates every host call from a Wasm extension. It:

  1. Checks the manifest's declared permissions
  2. Validates the call against the granted scope
  3. Routes to the actual host implementation
  4. Enforces per-call time limits (runWithTimeout)
  5. Logs every call for audit

This is the trust boundary. The SDK, the webview, the extension code — none of them are trusted. Only the broker decides what gets through.

The Registry

The registry (apps/web/) is a Next.js application backed by Prisma + Postgres (Neon). It provides:

  • REST API (/api/v1/): resolve, manifest, signature, bundle download, versions, publisher keys, tokens
  • Web UI: browse, search, detail pages, sign-in, dashboard
  • Publish pipeline: manifest validation, bundle policy enforcement, signature verification, WIT pin check, TOFU key pinning
  • Auth: NextAuth v5 with credentials + JWT strategy, scoped API tokens

The registry is designed to be replaced — any OCI-compatible registry works for bundle distribution. The oxp.sh registry adds publisher identity and the web UI on top.