Deploy with Vercel and Neon
In this tutorial, you’ll ask a coding agent to build a small Next.js notes app, create its Postgres database on Neon, and deploy it on Vercel. Both resources stay in provider accounts you own. Bahama gives the agent one safe workflow for planning the work, connecting the services, and verifying the finished app.
This tutorial is a great demonstration of how Bahama can provision and wire together multiple third-party providers into on secure application.
Before you begin
You need:
- Bahama installed;
- a Vercel account and a Neon account; and
- a coding agent open in an empty workspace or an existing Next.js project.
Your agent handles the implementation and commands. You complete provider sign-in, choose the correct team or organization when asked, and approve final plans.
Project Steps
Give your agent the complete outcome
Open Claude Code, Codex, or another coding agent in the workspace and try this:
Build a simple Next.js notes app backed by Postgres. Use Bahama to create the
database on Neon, make it available locally, and deploy the app on Vercel.
Handle the implementation and commands for me. Explain important choices in
plain language, and stop whenever Bahama asks me to approve a consequential
plan.Your agent prepares and inspects the application
For a new workspace, the agent creates the Next.js app and confirms that it builds. For an existing project, it preserves the current structure and first learns how the application works.
It then asks Bahama to inspect the workspace and read the live provider guides:
bahama inspect --json
bahama providers vercel --format agent
bahama providers neon --format agentThe agent confirms that Bahama detects Next.js, the normal build script, and the expected package manager. The provider guides explain what each driver manages and which official CLI it needs.
Your agent adds the database code
For this example, the agent installs Neon’s serverless JavaScript client:
npm install @neondatabase/serverlessIt reads DATABASE_URL only in server-side code:
import {neon} from "@neondatabase/serverless";
export function getSql() {
const connectionUrl = process.env.DATABASE_URL;
if (!connectionUrl) {
throw new Error("DATABASE_URL is not configured.");
}
return neon(connectionUrl);
}The agent must not expose this value through NEXT_PUBLIC_*, client components,
browser logs, or API responses.
Your agent adds an additive migration
The agent creates an ordered SQL file:
CREATE TABLE IF NOT EXISTS notes (
id BIGSERIAL PRIMARY KEY,
body TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);Bahama applies migration files in filename order and records their checksums in
_bahama_migrations. Never edit a migration after it has been applied; add a
new file for the next schema change.
Your agent describes the stack to Bahama
bahama init --name community-notes --application vercel --framework nextjs --database neonThe agent runs init to create a manifest for the whole stack. The file does
not contain an account ID, project ID, or connection string:
version: 1
project:
name: community-notes
application:
framework: nextjs
environments:
local:
provider: local
production:
provider: vercel
resources:
database:
provider: neon
engine: postgres
bindings:
DATABASE_URL:
from: resources.database.connectionUrl
to:
- environments.local.variables
- environments.production.variablesThe same database capability has two destinations. The local provider writes
it to the protected .env.local file; Vercel writes it to the production
environment.
Your agent checks what the providers need
bahama doctorDoctor checks the selected official CLIs and their current sessions. If a tool is missing, Bahama gives the agent the exact installation command. The agent should explain any global installation and ask before changing your machine.
When Bahama reports auth required, the agent starts login only for the
providers this project uses:
bahama auth login vercel
bahama auth login neonVercel and Neon own these login flows and credentials. Your agent launches the official commands, but you finish the browser or terminal authentication yourself. Bahama then verifies the resulting sessions.
You choose the provider accounts
A login may have access to more than one Vercel team or Neon organization.
Bahama will return decision required rather than selecting one silently.
Your agent should present the choices without guessing. Tell it which team and organization to use. It writes the selected non-secret values to the exact manifest paths returned by Bahama, for example:
environments:
production:
provider: vercel
config:
scope: example-team
resources:
database:
provider: neon
engine: postgres
config:
org: example-orgThese are account selectors, not durable resource IDs. Verified IDs belong in
bahama.lock.
You review the infrastructure plan
Once the choices are resolved, the agent asks Bahama for a plan:
bahama planFor a new stack, expect consequential work such as:
! Create the Neon project
! Apply the pending SQL migration
! Create the Vercel project
! Transfer DATABASE_URL to .env.local
! Transfer DATABASE_URL to the Vercel production environmentThe agent should summarize this plan and name the Vercel and Neon accounts it will use. Check those accounts carefully. If the plan matches what you asked for, tell the agent to approve and continue; you do not need to handle the plan ID yourself.
Notice that this plan prepares the infrastructure but does not publish the Next.js application.
Your agent applies exactly what you approved
After you approve the plan in the conversation, the agent applies its exact ID:
bahama apply plan_38d914fa2bc7 --approvedBahama creates or adopts the projects, applies the migration, transfers the
sealed connection URL to both environments, verifies every postcondition, and
writes bahama.lock.
At this point, .env.local contains DATABASE_URL with restrictive file
permissions and is protected by .gitignore. You do not need to open or copy
the value.
Your agent tests the app locally
npm run devThe agent exercises the server path that uses Postgres. If the application
cannot connect, it can run bahama status --json and inspect the application
error without printing the connection string.
You approve the first deployment
When the local app works, the agent asks Bahama to deploy it:
bahama deploy productionThe first deployment stops with an approval plan. The agent explains the Vercel account, project, framework, and production deployment step. If they look right, tell it to continue. The agent applies the exact plan ID Bahama returned:
bahama apply plan_b7a821c0e5d9 --approvedBahama publishes the current source, waits for Vercel to report the deployment ready, and verifies that the production URL responds.
Ask your agent to ship later changes
You can return later with a request such as:
Add the ability to delete a note, test it locally, and deploy the update.After implementing and testing the change, the agent runs:
bahama deploy productionBahama can apply a routine code-only redeployment immediately. A pending migration, changed provider configuration, framework mismatch, new resource, or rewired binding causes deployment to stop for another review with you.
What you own
The Vercel project and Neon database are ordinary resources in your accounts. They continue running if you stop using Bahama. The committed lock lets a future agent address those exact resources on another machine without depending on local provider link files or old conversations. You keep asking for outcomes; Bahama keeps the execution consistent and inspectable.
bahama detach --approved removes the complete local lock but does not delete
either provider resource. It is intended for deliberate forks and template
copies—not as a normal way to repair one missing resource.