
More and more teams are using Neon to power vibe coding platforms, so we decided to build one too – not as our billion-dollar-vibe-coding-startup-side-gig but as a public, open-source template you can use as a starting point to learn how to build codegen agents yourself.
We called the agent Aileen, and all the code lives here:
github.com/andrelandgraf/aileen** **
You can also try it out yourself here. Here’s how it looks in action:
Let’s walk you through how it works.
Aileen is an AI ch…

More and more teams are using Neon to power vibe coding platforms, so we decided to build one too – not as our billion-dollar-vibe-coding-startup-side-gig but as a public, open-source template you can use as a starting point to learn how to build codegen agents yourself.
We called the agent Aileen, and all the code lives here:
github.com/andrelandgraf/aileen** **
You can also try it out yourself here. Here’s how it looks in action:
Let’s walk you through how it works.
Aileen is an AI chat app and codegen platform that ties together everything you need to prompt (aka. vibe code) web applications front to back. It can
- Generate complete web apps from a prompt. You describe what you want to build and Aileen scaffolds it for you with the right files, dependencies, and setup.
- Provision a Postgres database automatically. Every app Aileen generates comes with its own database with schema and connection already configured.
- Add authentication. Each generated app also includes a working auth layer, so users can sign up, log in, and interact securely without extra setup.
- Track project versions. Aileen saves your generated apps and their versions so you can revisit previous iterations or roll back to an earlier state. Notably, your database always stays in sync with the selected project version.
- Run and preview apps instantly. You can test each generated project right from the UI or visit the preview URL directly. Even a VS Code for the Web instance of the development server is accessible through the UI.
- Keep context between generations. Conversations with Aileen aren’t one-off: the agent remembers your previous instructions and builds on them, enabling iterative creation.
- Scale down when idle. Because each app uses a serverless Neon database, unused projects automatically pause, reducing resource usage to zero when you’re not building.
Aileen UI. Note the versions list and the Create checkpoint button
The stack is intentionally modular, so you can swap parts without rewriting the world. At a high level, there’s a core platform that coordinates users, projects, and conversations, and a per-app provisioning flow that spins up isolated resources for each generated project.
Neon stores the platform’s own data: users, projects, projects versions…This is your source of truth for “what exists,” “who owns it,” and “what version is current.” Because it’s Postgres, you also get transactional safety for writes during multi-step generation flows.
Neon Auth handles sign-up/sign-in, session management, and user identity. The app checks this session on every request (server and API routes) and uses the authenticated user ID as the join key across projects, versions, and persisted chat. Defaults are compatible with RLS so you can enforce per-row access if you extend the schema.
Assistant UI Cloud renders the chat interface, streams model outputs, and keeps message state coherent across turns. All conversation data is persisted so threads survive refreshes, can be reloaded across sessions, and remain queryable for retrieval or long-term “memory.”
Mastra is the framework that executes tool calls and the multi-step agent loop. When a user asks for a new app or a change, the codegen-agent iterates on the prompt and decides what tools to call to fullfill the request (e.g. query or inspect the Neon database, read and write files on the development server, or search the web). Mastra Cloud is used to run the Mastra agent in a long-running environment that streams responses to the core platform’s Assistant UI chat.
You can also explore the Mastra Playground, which lists all available agents (in Aileen’s case, just one) and the tools they have registered. It’s a great debugging companion and lets you run the same agent logic locally before deploying it to Mastra Cloud.
Mastra Playground, with a list of all currently available tools
Vercel (app hosting & background tasks)
The core platform runs as a Next.js application deployed on Vercel. In addition to hosting the app, Vercel is also used to queue and execute longer-running background tasks. Creating a new codegen project (including provisioning a development server) can exceed the execution limits of serverless functions, so these operations are handled through Vercel Workflows. The Workflow Development Kit (WDK) makes it straightforward to build step functions that reliably orchestrate those tasks on Vercel. 👀
Freestyle (development servers & Git integration)
Freestyle.sh powers Aileen’s development environments. It gives the platform high-level primitives to:
- create new Git repositories for every generated app
- spin up isolated development sandboxes with filesystem and process access for the agent, and deploy apps to a lightweight, serverless runtime
Freestyle also includes a full MCP server, which exposes filesystem and process commands directly to the agent. In theory, Aileen could use it out of the box; in practice, the implementation relies on custom Freestyle tools for tighter control and easier debugging… And, honestly, just for fun 🙂
Each user-created project is isolated so one project’s experiments don’t interfere with another’s:
- **Dedicated Neon Postgres database (with snapshots). **On “create project,” the platform calls Neon’s API to provision a Neon project for that app. Each project’s data is isolated at the database level, and snapshots are used to capture version states over time. They are tied to the matching Git commit for consistent rollback and version history.
- **Auth configuration (via Neon Auth). **Neon Auth brings authentication and user management natively to your Neon Postgres database. Each code-generated app is automatically set up to work with Neon Auth so that the codegen agent can immediately start using user authentication utilities.
- Freestyle.sh** dev server with git integration. **Freestyle provides high-level primitives to create a new Git repository for each generated app, provision development sandboxes with filesystem and process access for the agent, and handle production deployments to a serverless environment.
We can break things down into two stages: project setup (handled by the control plane) and project iteration (driven by the agent).
When a new project is created, the control plane coordinates a full environment setup before the agent starts coding, with source repo, database, auth, and dev server.
Here’s how the control-plane, meta db Neon project looks like in the Neon console
- **Create Neon project (with Neon Auth) **The control plane calls the Neon API to create a new database inside a shared multi-tenant Neon organization. It also initializes Neon Auth for the project, generating client and server keys and registering callback URLs.
- Create new git repo. A new repository is created on Freestyle.sh. This will host all generated code and subsequent commits. The repository is based on a starter Next.js template that is set up to serve as a good starting point for the agent.
- **Request dev server (Freestyle). **The control plane sends a request to Freestyle to spin up a development server linked to the repo. This server will later run CLI commands for code scaffolding and preview builds.
- **Save credentials and secrets. **The resulting DATABASE_URL, Neon Auth keys, and other environment variables are stored securely in the meta database (the control-plane Postgres on Neon).
- **Retrieve initial commit. **Once Freestyle finishes scaffolding, the system retrieves the initial Git commit hash from the dev server using CLI commands.
- **Create initial snapshot (Neon). **The control plane calls Neon again to create a snapshot of the project database, capturing its initial state before the agent begins work.
- **Save version metadata. **The snapshot ID and Git commit hash are stored together as version 1 of the project in the control-plane database.
Once setup is complete, the agent steps in to plan and execute changes. Each agent execution starts with a prompt sent from the frontend (Assistant UI components) to Mastra Cloud. The agent has access to a toolkit composed of MCP servers (context7 for docs retrieval, Neon for database management) and several custom tools for environment variable management and interacting with the Freestyle development server.
- **Prompt. **The user describes what to build or change (“Add a notes table,” “Deploy a new route,” etc)
- **Agent reasoning. **The agent can take up to 50 steps per task, invoking tools, reading context, and iterating toward a solution.
- **Tool calls. **The agent uses:
- Custom tools to interact with the Freestyle development server’s filesystem and execute bash commands (ls, read_file, write_file, exec)
- Neon MCP tools to inspect the database, run SQL queries, and otherwise manage the project as it sees fit
- A custom commit and push tool that uses Freestyle’s git service to commit and push the changes and then create a new project version – more about that in the next step
- Environment-variable management tools to update the development servers’ environment variables (delete, list, add), later stored in the
project_secrettable. Theproject_secretstable stores all environment variables (like Neon Auth keys and database URLs) and versions them alongside each app release.* PS, Be aware hey’re stored in plain text for now; it’s a demo, after all 🙂 * - Context7 MCP server for optional documentation retrieval, letting the agent fetch external references on demand.
- **Completion, commit and push. ** Once the agent declares the task done, the system prompt instructs it to finalize the iteration by committing changes (calling the commit and push tool). The tool performs:
git commitandgit pushon the Freestyle repo- Retrieves the new Git commit hash
- Calls Neon to create a new snapshot of the project database
- Stores both identifiers (commit + snapshot) as the next project version in the
project_versionstable - Persists the latest environment variables in the
project_secretstable
- Version tracking. Each version pairs code and data: the Git commit represents code changes, and the Neon snapshot represents the exact matching database state. This guarantees you can always roll back or branch from any version with full fidelity.
Here’s how the code-generated projects look like in the Neon console
Checkpointing & versioning via Neon Snapshots
Aileen treats each version of an app as a lightweight checkpoint for both code and data. Every time the agent commits new code, a corresponding Neon snapshot captures the exact state of the project’s database (schema + data) at that moment. The Git commit hash and Neon snapshot ID are stored together, forming a perfectly synced record of that version.
You can easily jump between versions or fully revert back in case the agent messes up or you decide to discard made changes. This dual versioning model (Git for code, Neon for data) makes it safe to iterate, experiment, and recover from mistakes without losing alignment between your app and its database.
Here’s the create-snapshot API call:
const res = await fetch(
`${this.baseUrl}/projects/${neonProjectId}/branches/${prodBranch.id}/snapshot`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${this.apiKey}`,
Accept: "application/json",
},
body: JSON.stringify({
timestamp: options.timestamp ?? new Date().toISOString(),
name: options.name,
}),
},
);
The restore-snapshot API call:
const res = await fetch(
`${this.baseUrl}/projects/${neonProjectId}/snapshots/${snapshotId}/restore`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${this.apiKey}`,
Accept: "application/json",
},
body: JSON.stringify({
name: `before_restore_${Date.now()}`,
finalize_restore: true,
target_branch_id: targetBranchId,
}),
},
);
And the create-snapshot workflow:
export async function createManualCheckpoint(
projectId: string,
repoId: string,
neonProjectId: string,
currentDevVersionId: string,
secrets: Record<string, string>,
assistantMessageId: string | null,
) {
"use workflow";
const [currentCommitHash, snapshotId] = await Promise.all([
getCurrentCommitHash(repoId, secrets),
createCheckpointSnapshot(neonProjectId),
]);
const checkpointVersion = await createCheckpointVersion(
projectId,
currentCommitHash,
snapshotId,
assistantMessageId,
);
await Promise.all([
copyProjectSecrets(currentDevVersionId, checkpointVersion.id),
setCurrentDevVersion(projectId, checkpointVersion.id),
]);
return { success: true, versionId: checkpointVersion.id };
}
The Neon MCP server offers migration tools, but for Aileen, we decided to use Drizzle for managing migrations. Whenever the agent makes changes to the Drizzle schema, it is tasked to then generate the migration files and apply them using the drizzle-kit generate and drizzle-kit migrate commands. This makes migrations much easier to replay as they are part of the version controlled code base.
Here’s part of the system prompt:
Drizzle ORM (for schema management):
- Define and modify database schemas in Drizzle schema files
- Use Drizzle in the application code for type-safe queries
- Run schema changes via package.json scripts using the freestyle-exec tool:
- Generate migrations: \`cd /template && npm run db:generate\` (background: false - run in foreground to inspect output)
- Run migrations: \`cd /template && npm run db:migrate\` (background: false - run in foreground to inspect output)
- Never hardcode database credentials - use environment variables
Messages, tool runs, and planning notes are displayed with Assistant UI and persisted with Assistant UI Cloud so the agent can build context acrosss22 and sessions. That enables “continue where we left off,” auditability of what the agent decided, and retrieval of prior instructions when creating new versions. Referencing message identifiers with project version metadata also makes it easy to correlate a conversation turn with the version it produced.
Each generated project includes a schema for managing and versioning environment variables. Every project_version entry references its own set of secrets (database URL, Neon Auth keys, etc.) stored in the project_secrets table. This ensures that even if credentials or environment settings change later, historical versions remain reproducible. This is a simple implementation, but demonstrates how agents can manage environment state alongside code and data.
Every generated app gets its own serverless Postgres on Neon, which idles automatically when unused and wakes on demand. That’s a perfect fit for codegen/agent workloads, where bursts of activity are followed by long quiet periods. You can run lots of projects concurrently without carrying idle database costs.
**Use Aileen as your reference template for building your agent. **You can fork the repo, run it locally, or adapt it to your own setup: github.com/andrelandgraf/aileen
If you have any questions, you can find us in Discord!
Neon’s Agent Plan
If you’re building your own agent platform and need a backend,take a look at Neon’s Agent Plan. You can get special pricing, resource limits, and assistance to get your platform up and running.