An AI mobile app builder where the preview URL is already a real URL
The phone-share moment is where most tools in this category drop you. Build runs in the cloud, preview lives in an iframe, then a publish button stands between you and a URL anyone can open. mk0r cuts that out. Every sandbox is reachable at https://<vmId>.mk0r.com on the brand domain from the moment the agent's first turn ends. This is how that URL gets there and what changes once you have it.
The wall every other ai mobile app builder leaves in the way
Open the public guides for the popular tools in this category. Lovable, Emergent, Rork, Replit, Bubble, Appy Pie. The advice converges on the same loop: prompt, watch the in-app preview, iterate. When you actually want to put the build in front of a phone that is not in your hand, the playbook splits in two unhelpful directions.
One: ship the build through a native channel. That means Expo Go, TestFlight, an Android sideload, or a store submission. The tester installs an app, scans a QR, accepts a permissions sheet, and still gets a different binary than the one you built five minutes ago.
Two: publish to a hosted preview. That means logging in, finding the share toggle, flipping it to public, copying a slug from a modal, and asking the recipient to make their own account because the platform mistakes share links for invites.
Both detours exist because the in-editor preview lives behind the tool's own auth boundary, not in the open web. mk0r refuses to put that boundary there.
The 36 lines that turn a sandbox into a brand-domain URL
Most of the work happens in src/proxy.ts. It is a Next.js edge middleware that runs on every request that lands on our load balancer and decides whether the host header looks like a sandbox subdomain. If it does, the request is rewritten to the E2B ingress URL, transparently to the caller.
The vmId regex /^[a-z0-9]{15,30}$/ is what makes the wildcard safe. A real sandbox id is always lowercase alphanumeric in that length range, so a request forwww.mk0r.comfalls through to the marketing site, whileix37c4ka9q1mqyl3.mk0r.comgets routed at the cloud sandbox holding your build. There is no allow list to maintain. New sandboxes do not need a deploy step to be reachable; they just are.
Underneath, two pieces of infrastructure quietly carry the rest of the load. Cloud DNS holds an A record at *.mk0r.com pointing at our load balancer IP, and Certificate Manager owns a wildcard cert that covers every sandbox subdomain. Together they mean any sandbox id resolves and serves valid TLS without setup.
What happens when your phone hits the URL
Walk through one HTTP request, end to end. The phone is on cellular, the URL has been pasted into iMessage and tapped from the message bubble.
One tap from a phone, end to end
Nothing in that path requires the recipient to sign anything in. The cert is real, the host is the brand, the latency is one extra hop on top of the sandbox's own ingress. The phone treats it like any other web app, which is the entire point.
Why live reload survives the proxy
A static URL is one thing. A live one is another. The interesting property of <vmId>.mk0r.com is that the build keeps updating while the recipient holds the phone. That is not free; it is a single line of Vite config.
Without that line, the Vite client in the browser tries to open an HMR WebSocket back to the dev port directly. From a phone on a different network, that fails. With it, the client opens a wss://<vmId>.mk0r.com/ socket on the standard port that the proxy already terminates. The middleware happens to forward WebSocket upgrades, so the HMR channel rides through to the sandbox unchanged.
The visible result: you change a button color in the editor on your laptop, and the tester watching the URL on her phone sees the color change. No reload, no manual refresh. Most demos people remember are this kind of demo.
From your laptop to a home-screen icon, in four moves
With the URL behaving like a real URL, the share flow collapses to four steps. None of them requires a CLI, a tunnel, or an account on the recipient side.
The actual share flow
- 1
Type a prompt
Open mk0r.com, describe the app in one sentence.
- 2
Copy the URL
The editor shows https://<vmId>.mk0r.com once the sandbox boots.
- 3
Open it on the phone
Paste into iMessage, scan a QR, or text yourself the link.
- 4
Add to Home Screen
iOS share sheet installs it as a PWA with a real icon.
What the public URL gives you that an iframe cannot
The in-editor 390 by 844 frame is a perfect dev surface, but there are a handful of things only a real URL on a real phone can show you. These are the cases where the brand-domain preview pulls weight you would not get from any sandboxed iframe, no matter how good the editor is.
Things the URL unlocks that an iframe will not
- iOS share sheet "Add to Home Screen" with a real icon and standalone window
- navigator.mediaDevices.getUserMedia for camera and mic, which iframes block
- Service workers and offline behavior, since both require a real origin
- Push notifications wired through the iOS PWA permission sheet
- WebKit haptics and the iOS keyboard accessory bar, which iframes hide
- Real touch latency over the cellular network the user actually has
- Sharing the build with someone whose laptop is on a different continent
What sharing looks like elsewhere, and what it looks like here
The contrast lives in the steps the user has to perform between "I have a thing" and "you can use this on your phone." Below is the typical flow on a tool that gates sharing behind a publish action, and the corresponding flow on mk0r.
The share-flow tax, line by line
// 1. sign in to the platform with the magic link they emailed
// 2. open the project, click the canvas, hit the "..." menu
// 3. pick "Publish" and wait for the deploy job to finish
// 4. open the project settings, set visibility to Public
// 5. copy the share-link slug from the modal
// 6. paste the slug into a URL builder for the platform host
// 7. test the URL once to confirm the deploy actually went live
// 8. text the link with a note: "you'll need to make an account"The mk0r path is shorter because the URL is already alive. The traditional path is longer because most tools defaulted to a publish gate before anyone realized that a brand-domain URL is cheap once you own the wildcard cert and the middleware.
Three real reasons people use a phone-ready URL on day one
The patterns below come from how I have actually watched mk0r users hand off a build. Each one is a workflow that breaks the moment sharing requires an account or a publish step.
Pattern 1
Eat your own build during commute
Build it on a laptop in the morning, install it as a PWA on the phone before lunch, use it on the train home. The HMR channel keeps you on the latest version without reinstall.
Pattern 2
Hand it to a non-technical tester
Text the URL to a friend who has never heard of Expo Go. They tap the bubble, the build opens, they tell you what feels broken while you patch it from the same room.
Pattern 3
Show a client mid-call
On a video call, paste the URL into chat. The client opens it on the phone in their hand, and your next iteration appears on their screen as you ship it.
One detail to know about session lifetime
The brand-domain URL is bound to the sandbox id, not to a short-lived token. As long as the sandbox exists in any state (running, paused, restorable from Firestore), the URL resolves to it. When a session is fully released, the URL stops resolving and the proxy returns a 502.
The implication for sharing: the URL you pasted into iMessage on Monday will still work on Wednesday if you have not killed the session. If the recipient hits a 502, the agent can resume the same session and the URL comes back online without you having to send a new link.
Want to watch the share-flow run live?
Book a 20 minute call. We will spin up a sandbox, paste the URL into a phone, and ship a UI change while you hold it.
Frequently asked questions
What is the URL my in-progress mk0r app actually lives at?
Every active session has a public preview at https://<vmId>.mk0r.com, where <vmId> is the 15 to 30 character lowercase alphanumeric id of the E2B sandbox holding your build. The shape is set in src/app/api/publish/route.ts at line 95 and matched by the regex /^[a-z0-9]{15,30}$/ inside src/proxy.ts. There is no publish or deploy action that has to fire before the URL becomes reachable; the moment the sandbox boots, the URL responds.
How does a brand-domain subdomain end up pointing at a sandbox?
Two pieces line up. First, Cloud DNS holds an A record at *.mk0r.com pointing at 35.186.212.31, which is the LB IP for our Cloud Run frontend. Second, src/proxy.ts is a Next.js middleware that watches the host header. When the host matches <something>.mk0r.com and the something passes the vmId regex, the middleware rewrites the request to https://3000-<vmId>.e2b.app, which is the public ingress port the sandbox exposes for its reverse proxy. Result: your phone's browser sees a clean mk0r.com URL, and the bytes come from the cloud sandbox running your build.
Why does it matter that it is on the brand domain instead of an e2b.app subdomain?
Three reasons. First, iOS Safari treats real-domain HTTPS as first class for PWA installs and saved-to-home-screen behavior, so 'Add to Home Screen' produces a real icon, not a blocked notice. Second, the URL fits in an iMessage bubble without looking like a sandbox link, which matters when you are sending it to a non-technical tester or a client. Third, our wildcard cert covers every sandbox, so you do not get a TLS warning the way you would behind an ngrok tunnel or a self-signed cert.
Does live reload still work when the URL is opened on a phone?
Yes. The trick is in docker/e2b/files/app/vite.config.ts where the dev server is configured with hmr: { clientPort: 443, protocol: 'wss' }. That tells the Vite client to expect HMR over a TLS WebSocket on the standard https port, instead of trying to reach a non-TLS dev port directly. The middleware proxies the WebSocket through, so when the agent writes a file in /app/src on the cloud sandbox, your phone repaints without you ever touching the device. You can demo a change to a stakeholder while they hold the phone.
Do I need an account or a free tier to share the URL with someone else?
No account is required to start a build, and the preview URL is reachable from anyone's network without auth. The middleware that rewrites <vmId>.mk0r.com is unauthenticated by design; it is up to the app you generate whether the routes inside require sign-in. The contrast is sharp against tools that hide previews behind login, gate share links by tier, or require a workspace invite before a tester can open the build.
Is this a real native iOS or Android app?
It is a mobile web app built in a Vite plus React plus TypeScript scaffold and rendered in a 390 by 844 iframe inside the editor (the iPhone 14 Pro logical viewport). The same code runs at <vmId>.mk0r.com in any phone browser. From there it can be installed as a Progressive Web App via the share sheet on iOS or Android, or wrapped in Capacitor or Expo later for a store listing. The point of this page is the share-and-test loop, not the store-submission flow.
What happens to the URL if my session pauses or sleeps?
Sessions back themselves up to Firestore, including the vmId. When the sandbox is idle long enough to pause and you come back later, the same vmId is restored. The same <vmId>.mk0r.com URL keeps working because the middleware rewrites by id, not by some short-lived host. There is one caveat: a fully released session is gone, and the URL will 502. The dev console in the editor reports the session state.
How is this different from copying the live preview URL out of Lovable, Emergent, Rork, or Replit?
Lovable serves preview iframes but the public share link only works after you toggle the project to public, behind your account. Emergent and Rork ship the build via Expo Go, which requires the recipient to install Expo Go and scan a QR. Replit needs a Replit account to open most preview URLs. mk0r's <vmId>.mk0r.com is unauthenticated and lives on the brand domain from the moment the sandbox boots; the recipient does not need an account, an app, or a tunnel.
Type a sentence. Get a URL on the brand domain. Open it on the phone in your pocket.
Build a mobile app