AI App Builder, No Signup: what is actually running for you while you stare at the empty textarea
Most pages that brag about no signup are browser-only toy generators or they pop a form the second you click Generate. mk0r took the opposite trade. There is a complete Linux sandbox waiting for you behind that empty textarea, and the bill for it is on us. Here is exactly what runs, port by port, before you type a single character.
The honest definition of "no signup"
Almost every page that ranks for this topic is honest about one thing and dishonest about another. The honest part: you can preview without an account. The dishonest part: the moment you try to actually build, save, or run something, a form appears. The "no signup" was a thumbnail.
mk0r took the harder route. There is no form on submit, no paywall on first build, and no sleight of hand. The reason that works is also the reason most builders cannot offer it: behind every anonymous visitor is a real Linux sandbox that costs real money to run. We pay for it because the front door has to stay empty.
The single line that defines what you get
The whole story compresses to one line in our Dockerfile. This is line 102 of docker/e2b/e2b.Dockerfile:
Six ports. Each one is a real service running for you, the anonymous visitor. Not a placeholder. Not a tunnel. Not a client-side mock. Each port is bound to a separate binary that we baked into the template image.
What actually lives behind each port
3000
proxy.js, the only port the outside world sees. Routes /acp/, /mcp/, /sse, /screencast, /input, /vnc, and everything else to the right in-VM service.
3001
@playwright/mcp version 0.0.70, started in startup.sh with --cdp-endpoint http://127.0.0.1:9222. The agent talks here to drive the browser.
3002
acp-bridge.js. Claude Agent Client Protocol, version 0.25.0. The conversation surface for /api/chat. Receives prompts, streams updates back.
5173
Vite dev server. The pre-scaffolded React+TS+Tailwind v4 app at /app. HMR works. Your build streams here in real time.
5901
websockify in front of x11vnc on display :99. Lets the mk0r UI render a live VNC stream of the Chromium that the agent is driving.
9222
Chromium remote debugging. CDP endpoint. The Playwright MCP attaches here, so every click and screenshot the agent triggers is real.
The boot order, exactly as written in startup.sh
startup.sh is intentionally not set -e because non-critical services should not tear the whole sandbox down. The order matters and it is fixed.
Xvfb on :99
Xvfb -screen 0 1600x1600x24 -ac. The virtual display Chromium will draw into. Sleep 1 to give it a moment to settle.
brd-proxy.js on 127.0.0.1:3003
Local Bright Data upstream proxy. Dormant until /run/brd.conf exists. When you toggle residential IP on, the conf gets written and Chromium routes through here.
Chromium attached to Xvfb and the proxy
chromium --no-sandbox --disable-gpu --user-data-dir=/root/.chromium-profile --proxy-server=http://127.0.0.1:3003 --remote-debugging-port=9222 about:blank. Persistent profile, real window.
x11vnc on :5900
Streams the Xvfb display over VNC. -nopw -forever -shared, because the only consumer is the in-VM websockify on the same machine.
websockify on :5901
Forwards 0.0.0.0:5901 to localhost:5900, so the parent page can mount a VNC viewer over plain WebSocket without needing a native VNC client.
@playwright/mcp on :3001
npx @playwright/mcp --cdp-endpoint http://127.0.0.1:9222 --port 3001 --host 0.0.0.0 --allowed-hosts *. The agent's hand on the browser.
acp-bridge.js on :3002
Claude Agent Client Protocol bridge. Holds the long-lived ACP session, receives /initialize and /session/new, streams session/update notifications back.
Vite on :5173
cd /app && npx vite --host 0.0.0.0 --port 5173. The dev server for the pre-scaffolded React+TS+Tailwind app the agent will edit.
proxy.js on :3000
exec node /opt/proxy.js. The exec is intentional: this is the only process whose death takes the sandbox with it. Everything else runs in the background.
The provisioning that fires the moment you press send
The sandbox above is the part that warms before any user input. The part that fires when an anonymous visitor sends their first message is even less obvious, because nothing in the UI announces it. It happens inside getOrCreateSession at line 1346 of src/core/e2b.ts, and the actual function lives in src/core/service-provisioning.ts.
That call hits Neon's API at console.neon.tech/api/v2/projects and returns a real Postgres project: a host, a database name, a role, a password, and a connection URI. The next line writes those, plus a fresh GitHub repo URL and a Resend API key, into /app/.env inside the sandbox via execInVm.
The agent's first turn now has a working DATABASE_URL it can run migrations against. None of that required an email. None of it required a billing card. None of it required clicking anything.
The total bill the anonymous visitor never sees
What you do NOT have to do, that other tools require
Skipped friction
- Type an email address
- Pick a plan or enter a card
- Wait for npm install to finish
- Wait for Chromium to download for testing
- Provision your own Postgres database
- Create a GitHub repo manually
- Configure a Resend account for emails
- Set up VNC just to see the agent work
The architecture, drawn the way it actually works
Anonymous visitor on first message
The trade-off the anonymous mode has
We are not going to pretend there is no cost to skipping the form. There is exactly one. If you clear your browser storage, you lose the local mk0r_session_key, Firebase signs you out, and on the next paint we sign you back in as a brand new anonymous user with a fresh UID. Everything you built before is still in Firestore, but no browser holds its credentials anymore.
That is the trade we explicitly made. The fix is one click of Sign in with Google, which runs linkWithPopup on your existing anonymous user, keeps the same UID, and preserves every project. From then on, durability is permanent and cross-device. But the front door stays empty.
mk0r vs. the typical "no signup" AI app builder
| Feature | Typical no-signup tool | mk0r |
|---|---|---|
| What runs before you type | Nothing, or a client-side text generator | Linux sandbox, 6 ports, 9 services already up |
| Real Chromium with Playwright | No browser, can't actually test the app | Yes, on port 9222 + Playwright MCP on 3001 |
| Live preview surface | Static iframe of generated HTML | Vite dev server on 5173 + VNC stream on 5901 |
| Database | None, or in-browser localStorage | Neon Postgres provisioned per session |
| Source control | Copy-paste output only | Private GitHub repo created automatically |
| Email sending capability | Not available without an account | Per-app Resend API key in /app/.env |
| Cost to anonymous visitor | Hidden behind a signup wall on submit | Zero. mk0r pays the compute and provider bills |
Why most builders cannot do this
If your no-signup mode is just text-to-HTML, you have nothing to provision and nothing to bill, but you also cannot test the app you generate, persist data, or send an email from it.
If your no-signup mode is a real sandbox, every anonymous visitor costs you compute and third-party API credits. The only sustainable way to offer that is to either (1) make the cost low enough per visitor that it does not matter, or (2) accept that some anonymous visitors will become paying users and the rest are marketing spend.
We chose (2). The pool target size is 1 by default, set via VM_POOL_TARGET_SIZE, so there is always one warm sandbox sitting there waiting. When someone claims it, we boot the next one. The math only works because conversion to paid is real, but the optics are that the front door is genuinely free.
What a builder loses by demanding signup first
The reason every other tool makes you sign up first is that asking for an email shifts the cost calculation. Once they have your email, they can email you forever, even if you never built anything. So the math of giving you a free sandbox suddenly works, because the email is the asset, not the app. mk0r refused that deal.
Want to see what runs in the sandbox, live?
Walk through the prewarm, the provisioning, and a real anonymous build with the engineer who wrote it. Bring questions about your own onboarding.
Frequently asked questions
Is the no-signup sandbox actually a real VM or just a browser preview?
Real VM. Each anonymous visitor is matched to an E2B sandbox built from the mk0r-app-builder template defined in docker/e2b/e2b.Dockerfile. That template installs Node 20, Chromium, fonts, ffmpeg, postgresql-client, Xvfb, x11vnc, websockify, cron, the Playwright MCP server, and the Claude Agent ACP. The Dockerfile's last EXPOSE line is `EXPOSE 3000 3001 3002 5173 5901 9222`. Six live ports, all yours, no account required.
What's the boot order inside the sandbox before I send my first message?
docker/e2b/files/opt/startup.sh runs in this order: Xvfb on display :99, the local Bright Data residential proxy on 127.0.0.1:3003, Chromium pointed at that proxy with --remote-debugging-port=9222, x11vnc on :5900, websockify exposing VNC over WebSocket on :5901, the @playwright/mcp server on :3001 wired to the Chromium CDP, the ACP bridge on :3002, the Vite dev server on :5173, and finally proxy.js on :3000 which is the only port external traffic actually hits.
Do I get a real database without signing up?
Yes, on your first message. src/core/service-provisioning.ts exports provisionServices(sessionKey). It calls Neon's API at console.neon.tech/api/v2/projects, creates a fresh Postgres project tied to org-steep-sunset-62973058, and writes the resulting DATABASE_URL into /app/.env inside your sandbox. The path is src/core/e2b.ts line 1346, where provisionServices runs as part of getOrCreateSession. You never typed an email, but the agent now has a connection string it can run real migrations against.
Does no signup mean my work disappears when I close the tab?
No. mk0r issues a Firebase anonymous UID via signInAnonymously(auth) on first paint, plus a session key from crypto.randomUUID() persisted in localStorage as mk0r_session_key. Your sessions and projects in Firestore are owned by that UID, and the sandbox is recoverable on reload. Most no-signup tools keep state in window.localStorage only, so a refresh wipes everything. We chose the harder path so a closed tab is not a closed project.
Why expose port 5901 if I'm just typing prompts?
5901 is websockify in front of x11vnc. It lets the parent page render a live VNC stream of the Chromium running inside the sandbox. So when the agent navigates a page and clicks something to verify the app it just built for you, you can literally watch that browser do it. That kind of feedback loop is normally a paid feature behind a developer account elsewhere.
Where does the AI compute come from in anonymous mode?
The shared ANTHROPIC_API_KEY env var. When the prewarm runs in src/core/e2b.ts the ACP /initialize call is made with that key, and the ACP /session/new call mounts /app and installs the system prompt. When you actually send a message, src/app/api/chat/route.ts streams ACP events back. If you eventually sign in and connect Claude OAuth, your own subscription takes over, but anonymous users get the shared key transparently.
What gets provisioned on the very first message besides Postgres?
provisionServices runs four providers in parallel via Promise.allSettled. PostHog (a synchronous shared-project key plus a per-app appId for event isolation), Resend (a per-app restricted RESEND_API_KEY plus a fresh audience), Neon (a brand new Postgres project, role, password, and connection URI), and GitHub (a real repo created under m13v with both repoFullName and repoUrl). All five env vars land in /app/.env before the agent's first tool call.
How is this different from the open-source local builders like Dyad?
Dyad runs the generation pipeline on your machine with your own keys. You own everything, but you also have to host, install, and bring credentials. mk0r runs the equivalent stack as a managed sandbox, and the price of that for an anonymous visitor is exactly zero. No npm install, no API key, no auth flow. The trade-off is honest: you do not own the infrastructure, but you also do not wait for it.
Can I see what the running sandbox actually looks like?
When you have an active session, the in-VM Chromium is rendered through the websockify stream on port 5901. The mk0r UI mounts a VNC viewer that connects to that stream over WebSocket and shows the agent driving the browser. It is the same surface a developer would normally only get after signing up, paying, and configuring a debug connection.
By the time you read this, an anonymous visitor has triggered this exact sandbox boot more than 0+ times. None of those visitors typed an email first. Most of them never typed one at all.
Open the home page. The sandbox is already warm. The textarea is empty. That is the entire onboarding.
Build without signing up