# Originmain SDK Architecture
### From Proxy to SDK — System Design & Implementation Progress
> **Living document.** Updated every time a piece of this architecture is implemented.
> Supersedes `RENDERING-ARCHITECTURE.md` (proxy-era, now deprecated).
>
> Last updated: 2026-05-13
---
## Table of Contents
1. [Why We Moved Away From the Proxy](#1-why-we-moved-away-from-the-proxy)
2. [Target Architecture](#2-target-architecture)
3. [System Components](#3-system-components)
4. [Wire Protocol](#4-wire-protocol)
5. [Implementation Progress](#5-implementation-progress)
6. [Package Map](#6-package-map)
7. [Data Flow — Step by Step](#7-data-flow--step-by-step)
8. [Local Dev Problem & Tunnel Strategy](#8-local-dev-problem--tunnel-strategy)
9. [Edge Cases](#9-edge-cases)
10. [What Remains To Be Built](#10-what-remains-to-be-built)
---
## 1. Why We Moved Away From the Proxy
The original approach (`@originmain/cli`) ran a local HTTP reverse proxy that injected a
`` content | ✅ Yes |
| Hook installed too late | `__REACT_DEVTOOLS_GLOBAL_HOOK__` must exist **before** React's module body evaluates. Injected scripts run after HTML parses — after React is already loaded | ✅ Yes |
**The only reliable fix**: the fiber hook must be installed by the app itself, not by an external injector. That means it ships as an npm package the developer imports **before React** in their app entry point.
---
## 2. Target Architecture
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ ORIGINMAIN CLOUD (originmain.com) │
│ │
│ ┌─────────────────────────────┐ ┌──────────────────────────────────┐ │
│ │ Canvas (Next.js app) │◄───►│ WebSocket Bridge │ │
│ │ • Artboards / iframes │ │ /api/sdk/[projectId] │ │
│ │ • Inspector / Editor │ │ • auth via SDK token │ │
│ │ • File diff viewer │ │ • routes messages to user │ │
│ └─────────────────────────────┘ └──────────────────────────────────┘ │
│ ▲ │
└────────────────────────────────────────────────────────│───────────────────┘
│ WSS
│ (wss://originmain.com/api/sdk/[projectId])
┌────────────────────────────────────────────────────────│───────────────────┐
│ USER MACHINE (localhost / staging) │ │
│ ▼ │
│ ┌──────────────────────────┐ ┌────────────────────────────────────┐ │
│ │ Next.js dev server │◄───►│ @originmain/dev (SDK) │ │
│ │ (next dev / Vercel) │ │ • client runtime in browser │ │
│ │ │ │ • server runtime in Node │ │
│ │ │ │ • direct React fiber access │ │
│ │ Components.tsx ◄────────┼─────┤ • file-write capability │ │
│ │ │ │ • opens WSS to cloud canvas │ │
│ └──────────────────────────┘ └────────────────────────────────────┘ │
│ │
│ next.config.js — wrapped with @originmain/next plugin │
└─────────────────────────────────────────────────────────────────────────────┘
```
**Key invariant**: the fiber hook lives *inside* the user's app bundle.
No proxy, no injection, no external script — the user's `import '@originmain/live'`
is what instruments React.
---
## 3. System Components
### 3.1 `@originmain/live` (client runtime) — `packages/live-sdk`
The browser-side SDK. A side-effect import that:
- Installs `__REACT_DEVTOOLS_GLOBAL_HOOK__` **before React evaluates** (module-load time)
- Resolves the artboard ID from three sources in priority order:
1. URL fragment: `location.hash` contains `#__om_artboard=` ← primary, cross-origin safe
2. `window.name`: starts with `om:` (same-origin iframes only)
3. postMessage handshake: sends `{ __om_init_request: true }` to parent, awaits reply
- Runs the full postMessage protocol (see §4) once the artboard ID is known
- Is a **complete no-op** outside an Originmain artboard iframe (zero runtime cost in production)
### 3.2 `@originmain/next` (build plugin) — `packages/next`
A `withOriginmain(nextConfig)` wrapper for `next.config.ts` that:
- Prepends `@originmain/live` to every client-side webpack entry point
- Ensures the fiber hook import runs **before any other module** in the bundle
- Skips the server-side bundle (fiber hook is browser-only)
- Is idempotent (safe to wrap twice)
- Delegates to any existing `webpack` customisation in the user's config
### 3.3 `@originmain/dev` (full SDK) — `packages/dev` ❌ NOT BUILT YET
The full SDK intended for local development. Will combine:
- Everything in `@originmain/live` (client runtime, fiber hook)
- A **server runtime** that runs inside the Next.js dev server process
- A **WebSocket client** that connects outbound to the cloud canvas bridge
- **File-write capability**: receives design panel edits from the canvas and applies them to source files (`.tsx`, `.ts`, CSS modules)
### 3.4 WebSocket Bridge — `packages/app/src/app/api/sdk/[projectId]/` ❌ NOT BUILT YET
A Next.js API route on the cloud canvas that:
- Accepts an inbound WSS connection from `@originmain/dev`
- Authenticates via a project-scoped SDK token (issued in project settings)
- Routes messages bidirectionally:
- SDK → Canvas: `FIBER_TREE_UPDATE`, `ELEMENT_STYLES`, `ROUTES_DISCOVERED`, etc.
- Canvas → SDK: `PATCH_ELEMENT_STYLE`, `REQUEST_ELEMENT_STYLES`, `CAPTURE_SNAPSHOT`, etc.
- Maintains one WebSocket connection per active project session
### 3.5 Canvas (Next.js app) — `packages/app`
Originmain's cloud editor. Current transport: **postMessage via iframe**.
Future transport: **WebSocket via bridge** (for `@originmain/dev` local dev).
Key components:
- `LiveArtboard.tsx` — manages the `