Guide

An AI app builder where persistence is real from the first prompt

When a mk0r session boots, a fresh Postgres 17 database is created on Neon and its connection string is written into the VM's /app/.env file before the AI agent runs. No signup, no copy-paste, no localStorage. The first row your app writes lives in a real database.

m
mk0r
9 min read
4.9from 1,200+
Postgres 17 on Neon, per app
Zero accounts to create
DATABASE_URL injected before the first prompt

The thing every other guide leaves out

Most articles on this topic treat persistence as a checkbox: the tool either "has database integration" or it doesn't. That tells you nothing useful. The interesting question is when the database exists, who creates it, and how its credentials get to the code the AI is about to write. If those answers are vague, what you actually have is an app that looks persistent until you refresh the tab.

mk0r answers each question concretely. The database is provisioned inside provisionNeon(), it runs the moment your session starts, and the connection string is piped into /app/.env via execInVm before the agent ever opens a file. The rest of this page shows exactly that path.

What the provisioning step looks like

One prompt fans out into four real provisioned services in parallel. The Postgres database is the one that matters here, but the same path also creates a private GitHub repo, a Resend audience, and an isolated PostHog group so the rest of the app has somewhere real to send writes too.

One prompt, four real backends

Your prompt
Session key
App config
mk0r
Neon project
Resend audience
GitHub repo
PostHog group

The first 30 seconds, step by step

This timeline is taken straight from src/core/e2b.ts and src/core/service-provisioning.ts. Every step is a function call you can find in the open source.

1

Session boot

You type a prompt. mk0r grabs an idle E2B sandbox from the warm pool and assigns it your session key.

2

Neon project create

provisionNeon() POSTs to console.neon.tech/api/v2/projects with region_id aws-us-east-2 and pg_version 17. A fresh Postgres database is born.

3

Connection URI returned

Neon responds with connection_uris[0].connection_uri. mk0r also pulls the host, db name, role name, and role password.

4

Env file written into the VM

buildEnvFileContent() formats five database vars plus PostHog, Resend, and GitHub vars. execInVm pipes them into /app/.env via printf.

5

Agent reads the env

Claude wakes up inside the VM with the backend-services skill pre-loaded. It sees DATABASE_URL is set and defaults to Drizzle ORM with @neondatabase/serverless.

6

First write hits Postgres

The agent runs drizzle-kit push to create your tables, then writes rows over the Neon HTTP driver. The data is now durable.

The actual provisioning call

This is the function that runs against the Neon API. Region, Postgres version, and project name pattern are all fixed, which is why the database story is the same on every session. The whole thing is wrapped in a 30-second timeout because boot speed is part of the product, not an afterthought.

src/core/service-provisioning.ts

What lands in the VM's .env file

By the time the agent reads its first instruction, this is what the environment looks like. Five Postgres-related variables, plus the credentials for analytics, email, and source control. The agent can connect to a live database with a single line of code because the wiring is already done.

VM environment after provisioning

What "real persistence" looks like in the agent's code

The pre-loaded backend-services skill nudges the agent toward Drizzle ORM with the Neon HTTP driver. The schema below is representative of what you get back when you ask for "a habit tracker that remembers my streaks." There is no mock layer, no fake adapter; the migration runs against the same Postgres instance you saw in the env file.

generated by the agent

The anchor facts most other tools cannot match

Postgres 17

The Neon project is created with pg_version 17, the same Postgres release a serious team would pick for production. No legacy 13/14 fallback.

aws-us-east-2

Database lives in the same AWS region the E2B sandbox runs in, so the VM-to-DB round trip stays on the same backbone.

Five env vars, not one

DATABASE_URL, NEON_HOST, NEON_DB_NAME, NEON_ROLE_NAME, NEON_ROLE_PASSWORD. The agent can pick the connection style that fits the framework.

Drizzle by default

The pre-loaded backend-services skill names drizzle-orm and @neondatabase/serverless as the recommended path, with raw SQL as a fallback.

Dedicated, never shared

Project name pattern mk0r-<session-slug> guarantees a fresh schema per app. Two apps cannot read each other's rows.

Survives VM hibernation

The VM can sleep, restart, or get reissued. The Neon project keeps its data; mk0r re-injects DATABASE_URL on resume.

Fake persistence vs the real thing

A surprising number of AI app builders quietly swap localStorage.setItem in for "persistence." It looks the part until your user opens the app on their phone and the data is gone. Here is the difference, side by side.

Before vs after a real database

The default for most one-shot AI builders. Data is bound to a single browser profile and dies the moment you clear cookies, share a link, or switch devices.

  • Data lives in window.localStorage
  • Lost the moment you switch devices
  • Cannot be queried from a server route
  • Migrations are simulated, not real

How this lines up against the usual offer

FeatureTypical AI buildermk0r
Database created when you startSometimes, after extra promptingAlways, before the agent runs
Account you have to makeBuilder + database providerZero
Where the connection string livesOften pasted into chat by the userAuto-written into /app/.env
Postgres versionWhatever the free tier defaults to17
Data after a reloadOften gone (browser storage)Still there (Postgres)
Per-app isolationShared schema by defaultDedicated Neon project per session

Numbers worth pinning down

Big claims need small, verifiable numbers behind them. These four come straight from the source files linked in the steps above.

0Postgres major version
0DB env vars injected
0Signups required
0Dedicated DB per app
0s
Neon API timeout in provisionNeon
0
Chars in the per-app session slug

What the agent already knows about your stack

These are the names that show up inside the VM the second the session starts. You do not need to teach the agent any of them. It already has a skill that documents each one and shows it the right way to use them.

DATABASE_URLNEON_HOSTNEON_DB_NAMENEON_ROLE_NAMENEON_ROLE_PASSWORDdrizzle-orm@neondatabase/serverlesspg_version 17aws-us-east-2drizzle-kit push/app/.envexecInVm

Why this matters for what you are building

If your app keeps a list of things, accepts user input, or has users at all, persistence is the whole product. A great UI on top of browser storage is a demo, not a tool you can give to a friend. Every minute you spend wiring up Supabase or Postgres yourself is a minute you are not iterating on the actual idea. mk0r does that wiring for you, in the background, with a real database, before you have finished typing your prompt.

That is the gap most write-ups about this category never close. A checkbox that says "has database" tells you nothing. Reading service-provisioning.ts tells you everything.

Want to see the Postgres land in real time?

Book a 15-minute call and we'll walk through the provisioning trace on a live session, env file and all.

Frequently asked questions

Does mk0r actually create a real database, or is it just in-memory?

Real database. When a session starts, mk0r calls the Neon API and creates a brand-new Postgres 17 project named mk0r-<session-slug> in aws-us-east-2. It then writes DATABASE_URL plus four supporting env vars into /app/.env inside the VM before the AI agent runs. The agent connects with @neondatabase/serverless, runs migrations, and writes rows that survive page reloads, container restarts, and VM hibernation.

Do I have to sign up for Neon to use this?

No. mk0r provisions the database under its own Neon organization (org-steep-sunset-62973058) using a server-side API key. You never touch the Neon dashboard, you never copy a connection string, and you never enter credit card details on a third-party site. The whole flow is invisible from the prompt box.

Is the database shared between apps, or does each app get its own?

Each app gets its own dedicated Neon project. The slug pattern is mk0r-<first-12-chars-of-session-key>, so two apps cannot accidentally read each other's tables. This also means migrations never collide and you can drop the entire schema without affecting anyone else.

What ORM does the agent use by default?

Drizzle. The pre-loaded backend-services skill steers the agent to install drizzle-orm and @neondatabase/serverless, write a typed schema in src/db/schema.ts, and run migrations with drizzle-kit push. If you ask for raw SQL or Prisma, the agent will use those instead, but Drizzle is the default because it works cleanly with the Neon HTTP driver.

What about authentication and per-user data?

Pre-provisioned services in mk0r currently cover Postgres (Neon), email (Resend), analytics (PostHog), and a private GitHub repo. Auth is something the agent wires up on top of the database, typically with a sessions table, magic links via Resend, or a third-party provider you ask for. The DATABASE_URL is the foundation; auth is a layer above it.

Can I export the database and run my app somewhere else?

Yes. The Neon project is a real Postgres instance with full pg_dump support. Because mk0r also provisions a private GitHub repo per app and pushes the source code there, you can clone the repo, point it at any Postgres connection string, and run it without mk0r in the loop.

What happens if I refresh the page or come back tomorrow?

Session state, including the link between your app and its Neon project, is persisted to Firestore. When you reopen the app, the same DATABASE_URL gets re-injected into the VM and any rows you wrote yesterday are still there. The compute layer (the VM) is ephemeral, the data layer is not.

How does this compare to AI builders that store data in localStorage?

Browser storage looks like persistence until you switch devices, clear cookies, or share a link. The data is bound to a single browser profile. A real Postgres connection is bound to your app, which means the same data is visible from any device, surveys with multiple respondents actually work, and you can hit the database from a server route or a cron job. The trade-off is one extra network hop, which Neon HTTP makes cheap.

mk0r.AI app builder
© 2026 mk0r. All rights reserved.