Part 1 of this story was about moving user acceptance testing before expensive production construction. Application Preview gave DiagramCraft a way to build and run a conventional React/Vite application in the browser while substituting safe local services around it.
That alone was useful. It let us imagine a customer approving production-shaped application source before the project touched operational data or consumed a full deployment cycle.
But while we were finishing the implementation, we noticed a problem hiding in the phrase “local backend.” The code worked, but the mental model was still too attached to the frontend preview. If the React preview owned pgLite, then closing the app meant closing the backend. If another frontend wanted the same database, it received another copy. If a serverless function needed the database while the original app was gone, there was nothing left to answer the request.
That is when the feature changed shape. We stopped thinking about a preview with a mock backend and started thinking about a browser-local microservices runtime with applications as clients.
A small persistence question exposed the wrong ownership model.
The important leap was not “store pgLite in IndexedDB.” It was deciding what owns the state, who may share it, and how long it is supposed to live.
The first idea
Run a production-shaped React/Vite application inside DiagramCraft without spending deployment credits.
The first correction
A local Supabase backend cannot belong to the frontend tab if multiple frontends are expected to share it.
The second correction
Persistence is not a convenience. A named backend instance must survive preview shutdown, reloads, and source rebuilds.
The larger realization
Once the backend exists independently, React is only one client. Plain HTML, Pyodide, Constructs, emulated apps and MCP services can become clients too.
The new primitive is a named backend instance.
A project can provision it. Many clients can consume it. The backend persists independently of any one application.
A DiagramCraft Application Preview environment now has a backend instance identity. Think of that identity the same way you would think of a local Supabase project or a small development environment: it owns durable state and deployed services. A frontend connects to it. A backend-only project can provision it. Another frontend can consume it without becoming the owner.
This distinction sounds administrative until two applications need the same data. Then it becomes the difference between a simulation of a distributed system and two unrelated demos that happen to use the same schema.
PostgreSQL
PGlite persisted through IndexedDB, with migrations, roles, SQL, constraints and row-level security rather than an object-store imitation.
Auth
Local users and Supabase-shaped auth behavior belong to the named backend instance while client sessions remain client concerns.
Storage
Object bytes live durably in browser storage while bucket/object metadata and authorization remain aligned with the local database.
Realtime
Broadcast, Presence and postgres_changes are namespaced by backend instance so independent clients can observe one simulated system.
Serverless functions
Edge-style functions are deployed into the local backend and exposed through a same-origin gateway instead of depending on the frontend that authored them.
Control plane
A Local Backend Instance Manager exposes lifecycle, inventory, telemetry, deployed functions, workers, reset/delete operations and runtime health.
Origin → instance → services → clients
IndexedDB persistence solved more than reloads.
In the earlier implementation, local functions executed in the preview document because the document owned the pgLite database. That was a sensible local optimization under the old ownership model: a Worker could not use a database that only existed inside the page.
Once pgLite is persisted and opened through a worker-capable IndexedDB filesystem, that limitation changes. The database no longer needs to live where React lives. A worker-backed runtime can coordinate it, and a Service Worker can wake on demand to route function calls or other backend requests.
A Service Worker is not an always-on server. The browser can suspend it. That is a feature of the model, not a contradiction. Durable state belongs in IndexedDB, OPFS and cache storage; the runtime can be restarted and rehydrate from those stores when a request arrives.
The preview origin becomes the natural sharing boundary.
We already had an isolation feature in DiagramCraft. The backend architecture finally gives that setting deeper meaning.
If a backend outlives the app, it needs a control plane.
Persistent services are useful until nobody remembers they exist. Once DiagramCraft can leave behind databases, function deployments, Storage objects and registered Service Workers, visibility becomes part of correctness.
That led to another feature: a Local Backend Instance Manager at diagram, workspace and dashboard scope. The manager is intended to make the invisible browser infrastructure inspectable and deliberately controllable.
The control plane maintains a small per-origin runtime registry: which backend instances exist, which project provisioned them, which runtime version they use, what functions are deployed, when they were created, when they were last called, and whether the expected Service Workers still match what the browser reports.
That last part matters. DiagramCraft should keep a record of every Service Worker it intentionally installs, then compare that inventory with the browser’s actual registrations. Unknown or mismatched workers can be surfaced for inspection rather than quietly becoming permanent origin-level behavior.
The backend does not require a frontend anymore.
One of the most important consequences is almost comically simple: a valid project root may contain migrations, serverless functions and preview metadata but no `index.html`, no React entrypoint and no visual application at all.
That project is not broken. It is a backend service project. It can provision a named local instance, apply migrations, deploy functions, expose a gateway and remain available to other clients in the diagram.
That is where Application Preview starts to overlap with executable architecture modeling. A diagram can hold several independently structured project roots and let them behave like parts of one system.
React is now just client number one.
The architecture becomes much more interesting when every client uses the same transport rather than a private React-only shortcut.
The most exciting example is also one we are deliberately not implementing in this phase: an MCP service defined inside a DiagramCraft project root, hosted by the local runtime, and consumed by an LLM through the same simulated architecture. At that point a diagram can contain the service definition, its database, its functions, its MCP interface, a client application and the agent that uses it—all before any of it is deployed to conventional infrastructure.
Now we have to prove the combinations, not just the components.
Individual feature tests are necessary but insufficient. Database persistence can pass while function wake-up fails. Storage can pass while a second frontend receives the wrong namespace. Realtime can pass in one tab and fail across a shared backend. A service worker can register correctly and still become an orphan after an origin change.
So we added a validation-spike suite to the same DiagramCraft diagram. It starts with the most satisfying possible test—a tiny Vite/TSX application that should simply turn green—and escalates toward lifecycle, concurrency and full-stack combinations.
What changed under the hood?
The application-facing goal stays intentionally boring: ordinary project code should keep using ordinary APIs. The sophistication belongs in the runtime beneath it.
Why a worker-owned PGlite connection?
PGlite is effectively a single PostgreSQL connection. If every frontend, function and future Python worker opens competing ownership paths, local fidelity collapses under concurrency. A coordinated worker/runtime can serialize database access and preserve one authoritative instance.
Why both SharedWorker-style coordination and a Service Worker gateway?
They solve different lifecycle problems. An active worker coordinator is useful while several pages are alive and sharing a database. A Service Worker gives the origin a restartable request surface that can wake when no original frontend remains. The client contract should survive whichever internal topology is available in that browser.
How do local functions survive the provisioning page?
The source project can bundle a conventional function during a sync/deploy step. Deployment metadata and content hashes belong in the runtime registry; compiled/versioned artifacts can live in Cache Storage or another durable browser store. Invocation resolves the deployed artifact by backend instance and function name instead of reaching back into the closed page’s source tree.
What does teardown mean now?
Teardown means disconnect. Unsubscribe from Realtime, close transient handles, release listeners and let workers sleep. It does not delete Postgres, Storage, users, migrations or function deployments. Reset and Delete are explicit destructive control-plane operations.
How do seeds behave with a persistent backend?
`fresh-db` means the first creation of the named backend instance—not every app launch. `reset` runs after an explicit backend reset. `manual` runs only on command. Relaunching a frontend is no longer treated as database creation.
Does this mean DiagramCraft is becoming an infrastructure emulator?
In a limited but increasingly literal sense, yes. The goal is not to perfectly reproduce every cloud vendor inside a browser. The goal is to make architecture executable enough that real contracts, state transitions, service interactions, UAT flows and agent workflows can be tested before deployment. Remote and Hybrid modes remain the escape hatch when the local substrate should hand a service to the real environment.
What started as a cost-saving feature is becoming a new development surface.
The original motivation was pragmatic: give ChatGPT, Claude, Grok and other collaborators a place to build and test full applications without burning Lovable credits on every exploratory change.
That motivation still matters. But the architecture we ended up with points farther. DiagramCraft already treats diagrams as durable, executable models that can carry source, variables, constructs, Git projects, assets, decisions and AI collaboration. A persistent local service substrate means those models can begin to behave like the systems they describe.
A frontend can talk to a backend-only project. A backend function can persist after its authoring app is closed. Two project roots can intentionally share a database. A future Construct can invoke the same service a React app invokes. A Python worker can become another client. An MCP server can become another service.
Model the architecture. Run the architecture. Learn before deploying the architecture.
We are still early, and the validation spikes now matter more than the diagrams saying the design should work. But the direction is clear.
Application Preview began as a better way to move UAT left. The persistence correction turned it into something broader: a browser-local runtime where project roots can provision services, clients can share them, workers can wake them, and DiagramCraft can provide the control plane.
For customers, that means increasingly realistic software can be experienced and corrected before production commitments harden. For engineers, it means more of the architecture can be exercised as code rather than discussed as boxes and arrows. For AI-assisted development, it gives multiple agents a common executable environment as well as a common memory.
That is a much larger leap than getting React to render in a diagram.