Guide

Open Source AI App Builder: The Four Layers Hidden Behind the Label

Every guide on this topic puts a green check next to the word “open source.” None of them tell you which layer is actually open. Here is the audit, and the answer changes which tool you should pick.

M
Matthew Diakonov
11 min

The label is doing too much work

The phrase “open source AI app builder” is a coat hanger for products that share almost nothing with each other. One is a local Electron app that calls hosted models with your API key. Another is a hosted web app whose front-end source you can read but whose model orchestration runs behind a private endpoint. A third is a workflow platform you self-host on your own infrastructure that builds chatbots, not apps. A fourth is an internal-tools generator with a drag-and-drop canvas. They all sit on the same listicles under the same green check.

What every reader of those listicles actually wants to know is different. They want to know which part is open. The editor? The prompt that steers the model? The sandbox the generated app runs in? The code that decides which model to call and when?

Those are four different layers. A tool can open one and close the other three and still get the green check. The argument here is simple: do not buy openness as a single feature. Buy openness at the layer you plan to change.

The four layers, in order

Walk down the stack from the part the user sees to the part the model actually runs against.

1

Layer 1 — The shell

The editor UI, the prompt input, the file tree, the preview pane, the deploy button. This is the surface the user touches. Forking it lets you change the look, embed the builder somewhere else, or strip the parts you do not need.

2

Layer 2 — The brain

The system prompt that turns the underlying model into an app builder rather than a generic assistant. House style, framework choice, file conventions, when to verify, what to refuse. If this is closed, you cannot explain or change why output looks the way it does.

3

Layer 3 — The runtime

The sandbox where generated apps run. Browser-based (StackBlitz WebContainers, Sandpack) or container-based (E2B, Daytona, Modal). The runtime decides which packages, services, and tools the agent has access to. This is the hardest layer to fake and the one most people forget to check.

4

Layer 4 — The orchestrator

The code that picks the model, streams the response, decides when to retry, when to call a tool, when to verify in a real browser, and how to write the result back into the shell. Closed orchestrators are why two builders that look similar feel completely different.

How the popular options actually open up

Sourced from each project’s public documentation, repository, and pricing pages. Every cell describes which of the four layers the tool publishes. Pricing tiers and architectures shift over time; treat this as a snapshot, not a contract.

FeatureToolWhat you can fork
DyadLocal Electron app. Runs against any provider you bring (OpenAI, Anthropic, Google, local). Front-end and orchestrator are open.Shell, orchestrator. Brain and runtime depend on the model and sandbox you point it at.
Bolt.newWeb app. Runs generated apps inside StackBlitz WebContainers (a JavaScript Node reimplementation that ships in the browser).Shell published as bolt.new on GitHub. WebContainer runtime and the cloud orchestrator are not.
DifySelf-hostable LLM workflow platform. Builds agents and chat apps, not full custom apps with sandboxed code execution.Shell, orchestrator, and runtime if you self-host. Different shape from a code-generating builder.
Appsmith / ToolJetSelf-hostable internal-tools builders. Drag and drop, query bindings, JS expressions. AI assist is bolted on, not the core.Whole stack open. Best fit if your need is internal tools, not generated apps.
v0 / LovableHosted web apps. Generate React or Next.js code, sometimes downloadable. Editor surface and orchestrator are proprietary.You can pull the generated code out. Layers 1 to 4 themselves are not open.
Replit AgentHosted IDE plus agent that builds inside a real Linux runtime. Replit publishes some agent components; the orchestrator and editor are closed.Runtime is real and inspectable from inside. Shell and orchestrator are not yours to fork.
mk0rAI app builder. Quick mode streams Claude Haiku HTML; VM mode boots a Debian sandbox with Claude Code via ACP, and provisions a Postgres DB, transactional email, analytics, and a private repo before the agent reads a word.Shell is a Next.js 16 app at src/app. Brain lives in src/core/vm-claude-md.ts. Runtime is docker/e2b/e2b.Dockerfile. Orchestrator routes are in src/app/api.

Snapshot as of April 2026. Project licensing, scope, and architecture change; read each project's current docs before committing.

The runtime is the layer most lists skip

Here is the awkward part. The shell is easy to open because it ships as a web app and someone has to render it in a browser anyway. The brain (system prompt) gets opened sometimes, usually under the “templates” or “agents” label. The orchestrator gets opened in some local-first tools.

The runtime almost never gets opened in a meaningful way. A browser-based WebContainer lists what packages are supported but you cannot rebuild the runtime, install a CLI it omits, or seed the image with credentials. A hosted Linux sandbox is real but opaque: you do not know which packages are pre-installed, what ports are open, what proxy is in front of the agent’s HTTP client.

That matters because the runtime decides what your app can actually do during the build session. If the agent cannot install psycopg2, it cannot wire your app to Postgres. If the sandbox cannot launch headless Chromium, the agent cannot verify its own output by loading the page. If git is not in the image, the agent cannot clone the open source AI repo you wanted to build on top of. Every one of those is a runtime question.

Where each mk0r layer lives, by file path

Honesty cuts both ways. The point of this article is not to argue that mk0r is the most open option in the category. The most open option in the category is whichever self-hostable platform fits your shape. The point is to show what layer-by-layer transparency looks like when you actually do it.

Layer 1, the shell. mk0r is a Next.js 16 app. The landing surface is src/app/page.tsx. The phone-frame preview component is src/components/phone-preview.tsx and renders generated apps inside a 390 by 844 frame, the iPhone 14 logical viewport. Two-mode generation (Quick mode and VM mode) is wired through the same shell.

Layer 2, the brain. The system prompt that steers Claude during VM mode is plain TypeScript at src/core/vm-claude-md.ts. Two exported constants: globalClaudeMd at line 19 (role, workflow, code quality, styling, design constraints) and projectClaudeMd at line 1142 (Vite + React + Tailwind v4 specifics, the pre-provisioned services table). Lines 1182 to 1187 list the four services wired into /app/.env before the agent reads a single prompt: PostHog, Neon, Resend, and a private GitHub repo. If you wanted to change house style, you would edit the same TypeScript file you edit any other module.

Layer 3, the runtime. The Dockerfile is at docker/e2b/e2b.Dockerfile, 103 lines, FROM debian:bookworm-slim. Lines 26 to 35 install the apt block: chromium, fonts-liberation, libgbm1, libnss3, libnss3-tools, libxss1, ffmpeg, xvfb, x11vnc, websockify, python3, python3-pip, postgresql-client, cron, and git, plus Node.js 20 from NodeSource. Lines 52 to 57 pin global npm packages: @playwright/mcp@0.0.70, ws, @agentclientprotocol/claude-agent-acp@0.25.0, @anthropic-ai/claude-code, and social-autoposter. The agent has those exact tools in PATH the moment a session boots. The build context is prepared by npm run e2b:prepare and the image is rebuilt only when the Dockerfile or the files it copies in change.

Layer 4, the orchestrator. API routes under src/app/api/. The Quick path is a streaming Claude Haiku call that emits HTML directly. The VM path opens a session against the E2B sandbox, attaches Claude Code via the Agent Client Protocol bridge (the package pinned in the Dockerfile), and screencasts the in-VM Chromium back to your tab over websockify. Streaming, session reuse, and residential-IP swap are all in the same TypeScript code path, not behind a private API.

What the layer story changes for a user who wants to fork

You like the output of a hosted AI app builder but the default style is wrong for your brand. You write a support ticket asking how to change the system prompt. The reply is that the system prompt is private. You can override style by adding instructions to every prompt, which works inconsistently because the closed prompt has its own ideas. You either live with the default or move tools.

  • System prompt is opaque
  • Runtime image is opaque
  • No way to swap models for free credits or local inference
  • Style overrides fight the closed prompt

How to actually pick, in three honest questions

  1. What do you plan to change? If the answer is “the editor look,” any open shell is fine. If it is “the model,” you need an open orchestrator. If it is “what the agent has access to while building,” you need an open runtime image. If it is “why the agent makes the design choices it makes,” you need an open system prompt. Pick by the answer, not by the binary check.
  2. Are you going to self-host? Self-hosting is a runtime question first. Most browser-based tools cannot be self-hosted in a meaningful way because the runtime ships in the user’s tab and the orchestrator talks to a private cloud. Real self-hosting needs the runtime image plus the orchestrator, both, and ideally with the same build steps the vendor uses.
  3. Are you actually going to fork, or do you just like that you could? Most people in this space pick a tool because it claims openness, never fork it, and would have been better served by the closed tool with the better hosted experience. There is no shame in just using the hosted thing. The point of this article is that “open source” is not the tiebreaker most lists make it out to be. The tiebreaker is the specific layer you intend to touch.

The honest limit

None of this means closed builders are bad. Several of the best user experiences in this category are closed end to end. They iterate faster, they ship polish that open competitors do not, and they remove decisions a non-developer should not have to make.

What is wrong is treating “open source” as a single buying signal. It is four signals stacked into one word. Pull them apart, decide which ones you actually need, and the field of options gets a lot smaller and a lot easier to choose from.

Want to walk through the layers on a real build?

20 minutes, screen share. We open the Dockerfile, the system prompt, and the orchestrator while you watch a real session boot, and you keep the link to the resulting app.

Frequently asked questions

Is calling something an open source AI app builder enough to know what I am getting?

No, and that is the whole point of this article. The label gets used for tools where only the editor UI is open, for tools where the editor plus the orchestrator are open but the model is closed, for tools where everything from the shell to the runtime image is published, and for self-hostable platforms where you bring your own model. They are not the same product. Ask which layer is open and which is not, then match that to what you actually plan to change.

What are the four layers exactly?

The shell is the editor surface, the prompt input, the preview, and the file tree. The brain is the system prompt that turns the model into an app builder rather than a generic assistant. The runtime is the container or sandbox where the generated app actually runs (image, packages, services). The orchestrator is the code that decides which model to call, how to stream the output, when to verify, and how to wire the result back to the shell. Each one is a separate fork target.

Which layer should I care about most?

Depends on what you want to do. If you want to self-host, the runtime is the layer that has to be open. If you want a different model, the orchestrator is the layer that matters. If you want different output style or different code quality defaults, the brain is the layer to fork. If you only want a different look and feel for the editor, the shell is enough. People often pick a tool based on the easy layer to open and then discover the layer they actually need is closed.

Where does mk0r sit on this map?

mk0r is a Next.js 16 app, the system prompt that steers Claude during VM mode lives in TypeScript at src/core/vm-claude-md.ts, the runtime image is a Debian bookworm-slim build with pinned package versions defined in docker/e2b/e2b.Dockerfile, and the orchestrator routes are in src/app/api. The runtime is the most distinctive layer: lines 26 to 35 of the Dockerfile install chromium, ffmpeg, xvfb, x11vnc, websockify, python3, python3-pip, postgresql-client, cron, and git, and lines 52 to 57 pin agent packages including @playwright/mcp@0.0.70 and @agentclientprotocol/claude-agent-acp@0.25.0.

Why does the system prompt count as a layer of openness?

Because it is where most of the product behavior actually lives. The model is a general assistant. The system prompt is what makes it default to mobile-first Tailwind, three colors maximum, no decorative icons, build first then verify. If the prompt is closed, you cannot tell why your output looks the way it does or how to change it. In mk0r, the prompt is exported as plain TypeScript constants (globalClaudeMd starts at line 19 and projectClaudeMd at line 1142 of vm-claude-md.ts) so the steering is editable like any other source file.

How is the sandbox runtime different from the shell?

The shell is what you see in the browser when you open the builder. The runtime is what runs the generated app while it is being built. In tools that use a browser-based runtime (StackBlitz WebContainers, Sandpack), the runtime is a JavaScript reimplementation of Node that runs in your tab. In tools that use a real container (E2B, Daytona, Modal), the runtime is a Linux image you can rebuild. mk0r uses E2B with a custom image. The build context is prepared by npm run e2b:prepare and the recipe is the Dockerfile.

Are closed builders worse than open ones?

Not automatically. Closed builders trade openness for polish, support, hosted infrastructure, and (often) faster iteration. The trade-off is real and it is fine to take it. The argument here is not that open is morally better. It is that the word covers four different things, and a shopper should know which one a given tool actually offers before treating openness as a buying point.

Can I use mk0r without thinking about any of this?

Yes. mk0r is also designed to be the no-account, no-setup option. You can open mk0r.com, type a sentence, and watch an app stream into a real preview without ever caring how the layers are stacked. The four-layer audit is only relevant if you plan to fork, self-host, or change the model. For people who just want the prototype, the layer story is invisible.

Open mk0r and watch the four layers stack up live. No account, no setup, just a sentence and a streaming preview.

Build at mk0r.com
mk0r.AI app builder
© 2026 mk0r. All rights reserved.