The App Lives in the Worker, Not the DOM

repojavascriptfrontendweb-workersmulti-threadingactor-modelai-nativeperformancearchitecture

Actor model isolation in workers mirrors Inngest's durable function isolation; AI-inspectable runtime state addresses the same agent ground-truth problem the joelclaw system solves with OTEL

Neo.mjs runs your entire application in a dedicated Web Worker — not as an optimization you add when things get slow, but as the default. The main thread does one thing: update the DOM. Business logic, state, component trees, event handling — all of it lives in the App Worker. They call this Off-Main-Thread (OMT) architecture, and it inverts the standard frontend mental model. Most frameworks treat workers as a place to exile heavy computation that’s already proven blocking. Neo.mjs treats the worker as home base.

The real consequence of this is that UI components are persistent objects in memory, not ephemeral render results. When a React component renders, JSX compiles to function calls, executes, and produces DOM nodes — the component “instance” is gone. Neo.mjs components are objects with state, methods, and an inheritance chain that persist in the worker’s memory for the application’s lifetime. The README puts it plainly: “components are persistent objects — not ephemeral render results.” That’s not a small implementation difference. It’s a different model of what a component is.

Where this gets genuinely interesting is AI. The repo makes a pointed argument: agents working with React are effectively blind because the code they write (JSX/templates) is destroyed by the build step, leaving only DOM nodes with no relationship to the source. In Neo.mjs, the map is the territory — an agent can query a running component’s state, methods, and position in the component tree at any time because those objects are alive in the worker. They call this access point the “Neural Link.” The v11 release also ships a suite of MCP servers — a semantic knowledge base powered by ChromaDB and Gemini embeddings, a persistent memory core for agents, a GitHub workflow server, and an agent runtime that can execute scripts against live application state. Whether all that lives up to the marketing is an open question, but the underlying architectural argument is solid: an inspectable runtime is fundamentally more agent-friendly than compiled output.

The Actor Model framing is worth noting — each worker is an isolated actor with its own state communicating through message passing, which is structurally the same isolation model that makes Inngest durable functions reliable. Multi-window orchestration falls out naturally from this: if your app state lives in a worker rather than being tied to a browser tab’s main thread, spanning multiple windows becomes tractable instead of arcane. They’re positioning this for financial/trading platforms, IDEs, and control rooms — not content sites. They explicitly say “use Astro or Next.js for that,” which is refreshing honesty in a framework README. This is for stateful, complex, long-running SPAs where the threading model actually matters.

Key Ideas

  • Off-Main-Thread by default: Entire app — logic, state, component trees — runs in a dedicated Web Worker; main thread only applies DOM patches
  • Persistent component objects: Components are long-lived runtime objects, not recreated per render — closer to desktop application objects than React’s functional model
  • Actor Model architecture: Each worker is an isolated actor with message-passing interfaces; the same isolation model that makes Inngest durable functions predictable
  • AI-inspectable runtime: Because component objects persist, agents can query live state, methods, and inheritance chain — no gap between source and runtime reality (the “Neural Link”)
  • MCP suite in v11: Ships with Knowledge Base MCP (ChromaDB + Gemini), Memory Core MCP, GitHub Workflow MCP, and an Agent Runtime for autonomous script execution
  • Multi-window orchestration: App state independent of any single browser tab; their stated sweet spot is multi-screen financial dashboards, IDEs, and control rooms
  • 130k+ lines of production code: Enterprise-grade, not a proof of concept — has real financial-sector deployments
  • Explicitly not for content sites: Positioned against Next.js and Astro use cases — this is for complex stateful SPAs, and the README says so plainly