Guide

AI Web UI Generation: What Actually Runs Between Your Prompt and the UI

Every listicle about AI web UI generation ranks the same seven tools. None of them tell you the thing that actually determines output quality: the substrate the model streams code into. Here is what that looks like on mk0r, with file paths you can verify.

m
mk0r
8 min
4.8from 10K+ creators
Pre-warmed Vite + React + Tailwind v4 sandbox
15-second TTFT watchdog with auto-eviction
No signup, no setup, first prompt is free

The substrate is the product

If you compare AI web UI generators by their marketing pages, they all sound the same. Describe something, see a UI. The differences are at a layer nobody writes about: what the model is allowed to do, what it is pointed at, and what fails gracefully when it does not work.

mk0r treats that layer as the product. The sandbox, the dev server, the browser, the watchdog, the one-sentence system prompt. This page is a walkthrough of that substrate, because it is what separates a UI that feels alive from one that feels like a screenshot.

What a prompt actually travels through

A single prompt hits several systems in order. This is the shape of that pipeline on mk0r. The hub is the agent; the left side is what feeds it; the right side is what it controls.

Your prompt, the agent, the UI it writes

Your prompt
Session UUID
Pre-warm VM
Claude agent
Vite dev server :5173
Tailwind v4 compiler
Playwright on :9222

The first fifteen seconds, as the server sees them

On mk0r, the instant the page mounts we hit /api/vm/prewarm to reserve a warm sandbox out of the pool. By the time you stop typing, your VM is sitting there with a dev server and a browser, waiting. Here is what the server-side trace looks like for a typical request.

/api/chat (server trace)

The agent's entire system prompt is one paragraph

This is the anchor fact of the page, and you can check it yourself. The mk0r repo exports a single constant called DEFAULT_APP_BUILDER_SYSTEM_PROMPT, defined on line 148 of src/core/e2b.ts. That constant is the entire context the agent starts with. Every other rule it follows is read at runtime from CLAUDE.md files inside the sandbox.

src/core/e2b.ts

Most AI UI generators hide behind a wall of behavioral instructions: do this style, not that, produce in that framework, use this library, write in this tone. mk0r uses fifty-nine words. The stack is named, the port is named, the browser is named, and the rest lives in the repo the agent is editing.

How the UI you see unfolds

Here is the sequence, from you hitting send to a rendered UI you can actually click.

1

Page mount: pre-warm a VM

On first render the client calls /api/vm/prewarm and the Cloud Run worker reserves an E2B sandbox from the pool. You never see this happen; it is done before your first keystroke.

2

Submit: attach your session to that VM

A UUID in localStorage under key mk0r_session_key binds your tab to the same sandbox across refreshes. If the VM went to sleep, the server restores it and re-installs /run/brd.conf idempotently.

3

Stream: boot_progress, then session, then tokens

The server streams NDJSON. You get boot_progress frames, then a session frame with previewUrl, vmId and the available models, then agent_message_chunk frames as the model writes code.

4

Run: Vite hot-reloads every edit

As the agent writes files, Vite's HMR on port 5173 updates the preview without a full reload. Tailwind v4 compiles on demand; utilities appear as the class names show up in the source.

5

Test: Playwright drives the preview

Playwright MCP is bound to Chromium at CDP 127.0.0.1:9222. The agent can navigate, click, and snapshot its own UI. Browser tool calls are detected in the client via /^(mcp__playwright__)?browser_/.

6

Evict or resume, not hang

If the agent stays silent for 15 seconds, the TTFT watchdog in /api/chat kills the stream, evicts the session, and tells you to retry. Your next click gets a fresh VM.

Numbers that describe the substrate

None of these are marketing figures. They are constants in the repo. Read src/core/e2b.ts and src/app/api/chat/route.ts if you want to verify.

0sTTFT watchdog
0Vite dev port
0Chromium CDP port
0Words in system prompt

What 0 setup steps gets you

A fresh mk0r sandbox already has these things installed and wired. You do not configure any of them. You do not see any of them. They are the floor beneath your prompt.

Vite dev server on :5173

Pre-running with HMR. Every file the agent writes hot-reloads in the preview without a refresh.

React + TypeScript

Scaffolded at /app with src/main.tsx as the entry point and src/App.tsx as the root component.

Tailwind CSS v4

Wired via Vite plugin, entry at src/index.css with @import "tailwindcss". No tailwind.config.js.

Playwright MCP on CDP :9222

@playwright/mcp binds to pre-installed Chromium at /usr/bin/chromium. The agent tests its own UI in a real browser.

Session UUID (no signup)

A random UUID is written to localStorage under mk0r_session_key. That is the entire identity layer for anonymous builds.

Voice input (Deepgram Nova-2)

Microphone captures audio/webm;codecs=opus and transcribes via /api/transcribe. Dictation to UI, no signup.

The 15-second watchdog, in the source

Silent failures are the worst failure mode in AI UI generation: you wait two minutes, nothing appears, and you do not know whether to wait longer or start over. mk0r forecloses that mode at fifteen seconds. The code is short; it lives in src/app/api/chat/route.ts around line 421.

src/app/api/chat/route.ts

How this compares to the listicle default

Search for "ai web ui generation" and the top results are rankings of seven tools with similar surface features. The axes that matter at build time rarely appear in those posts. Two framings of the same product, side by side.

Listicle framing vs. substrate framing

- Text to UI support: yes
- No-code promise: yes
- Templates available: yes
- Design fidelity: "high"
- Code export: yes
- Team plan: yes
- Free tier: yes
-14% fewer lines

A shortlist you can verify

If you are evaluating an AI UI generator and want to avoid the listicle trap, these are the questions to ask about any tool. These are the answers for mk0r.

Verifiable properties of mk0r

  • Session starts with zero signup (session UUID only)
  • System prompt is one paragraph (src/core/e2b.ts:148)
  • Sandbox boots Vite + React + TS + Tailwind v4 at /app
  • Dev server runs on port 5173 with HMR pre-enabled
  • Playwright MCP wired to Chromium on CDP :9222
  • 15-second TTFT watchdog auto-evicts wedged sessions
  • Free tier pinned to Claude Haiku (FREE_MODEL constant)
  • Every file stays real code you can download and edit

Who this matters to

If you are shipping a prototype at 11pm, none of this is visible to you and that is the point. The substrate earns its keep when the model makes a bad call and the system catches it, or when you come back two days later and your sandbox restores from sleep instead of starting from zero.

If you are a developer evaluating AI UI tools for a team, this is the layer to compare. A beautiful generated screenshot is table stakes. A loud failure mode, a pre-warmed runtime, and a browser the agent can drive are what separate a toy from something you can iterate on.

Vite :5173 + HMRReact + TypeScriptTailwind v4Playwright MCPChromium CDP :9222E2B sandboxClaude Haiku (free)NDJSON streaming15s TTFT watchdogSession UUIDPre-warm on mountVoice input (Deepgram)

Frequently asked questions

What is AI web UI generation, technically?

It is a pipeline. A language model reads your prompt and emits code (HTML/CSS/JS, or React + TypeScript) into a runtime that can render that code. The quality of the UI depends on both halves: the model's output and the runtime's ceiling. If the runtime is just a raw HTML string, you get a static page. If the runtime is a live Vite dev server with HMR, a real browser, and a testing tool, you get something the agent can iterate on.

How is mk0r's approach different from Lovable, Emergent, or Framer AI?

mk0r removes the account wall and exposes the substrate. You land on mk0r.com, your browser gets a session UUID, and an E2B sandbox is pre-warmed for you before you finish typing. The agent runs inside that sandbox with Vite + React + TypeScript + Tailwind CSS v4 already installed on port 5173 with HMR, plus Playwright MCP pointed at Chromium on CDP port 9222. You never sign up, you never wait for an environment to provision, and the agent can test its own UI in a real browser without you configuring anything.

What is the 15-second TTFT watchdog and why does it matter?

TTFT means time to first token. In src/app/api/chat/route.ts, mk0r sets a 15 second timeout at line 421 called ttftMs. If the agent does not emit any notification within that window, the session is marked wedged, evicted from the pool, and the next request boots a fresh VM. This is the difference between an AI UI generator that sometimes hangs silently and one that fails loudly and recovers. It is also the reason a retry in mk0r almost always works: the stuck worker is gone before you click retry.

Do I get real code I can edit, or a black box?

Real code. The VM mode scaffolds a normal Vite + React + TypeScript project at /app inside the sandbox. Files include vite.config.ts, src/main.tsx, src/App.tsx, and src/index.css with Tailwind v4's @import. You can download the project and continue developing in any editor. Nothing is a proprietary format.

What can the agent actually do inside the sandbox?

It can read and write files, run the dev server, and drive a headless Chromium via Playwright MCP on CDP endpoint http://127.0.0.1:9222. Browser tool calls are detected in mk0r's UI via the regex /^(mcp__playwright__)?browser_/ so the preview surface knows when the agent is testing the UI. In practice this means the agent can click through its own generated UI, catch layout bugs, and fix them before you see a broken preview.

Does mk0r really have a one-sentence system prompt?

Yes. The constant DEFAULT_APP_BUILDER_SYSTEM_PROMPT is defined at src/core/e2b.ts line 148. It is one paragraph that tells the agent it is inside an E2B sandbox with Vite + React + TypeScript + Tailwind CSS v4 at /app, the dev server is on port 5173 with HMR, Playwright MCP is available, and that CLAUDE.md files in the repo carry the detailed workflow instructions. Everything else the agent knows comes from reading the CLAUDE.md files at runtime.

What model does free usage run on?

Claude Haiku. FREE_MODEL is pinned to the string 'haiku' at src/app/api/chat/model/route.ts line 5. If a signed-in user with an active subscription calls the model switch endpoint, they can move to Sonnet or Opus. Anonymous users stay on Haiku, which is also the default model set on every session init.

How long does a UI actually take to appear?

In Quick mode, streaming HTML starts within seconds and the visible app reaches a working state in under 30 seconds. In VM mode, the E2B sandbox is pre-warmed via /api/vm/prewarm on page mount, so by the time you finish typing your prompt the Vite dev server is already running and the preview URL is ready to frame in. Typical first-paint on a VM app is 1 to 3 minutes depending on how much the agent builds.

Try the substrate, not the screenshot

Open mk0r, type one sentence, watch the sandbox come alive. No account. No setup. The dev server is warming up already.

Build a UI now