Build a Next.js + PostgreSQL app with AI, step by step to live

Build an income and expense book with Next.js + PostgreSQL, written and deployed to BrewInTH by AI: prompts for each step, the Prisma release command, fixes.
You want more than a page that shows information: a site with a login that saves data to a database and works from your phone anywhere. Next.js + PostgreSQL is one of the pairs AI writes best. Yet going live tends to trip on the same things: the database tables never get created, the build fails because it can't reach the database, or the site comes up and the home page throws an error.
This article builds a real app step by step — a simple income and expense book for a small shop — from creating the project on BrewInTH, through writing it with AI, to going live and making the next round of changes. Every step comes with a prompt you can copy.
In short
✅ Create a project with Node.js and a PostgreSQL database; the platform gives your appDATABASE_URLon its own
✅ Let an AI that works on your computer (Claude Code, Codex, Cursor or Windsurf) write and deploy it with the link + token
✅ Tables are created by the release commandnpx prisma migrate deploy, not during the build
✅ Pages that read the database must render when someone opens them, not at build time
✅ For the next change, continue in the same chat: the AI adds a new migration and deploys again
What you'll have at the end
An income and expense book: the shop owner signs in with a password, records entries (date, category, income or expense, amount, note), sees monthly totals and downloads everything as a CSV file. All the data lives in PostgreSQL on BrewInTH, and the site opens from a phone at the project's HTTPS address.
What you need:
- A BrewInTH account (the Free package works: one project and one database)
- A computer with Node.js and a coding agent such as Claude Code, Codex, Cursor or Windsurf. This part can't be done from a phone yet.

Step 1: Create the project on BrewInTH
- In the console, click Create project and give it a name, such as "Income and expense book".
- Under Website/app technology, choose Node.js (or let the platform decide; it checks your code on the first deploy).
- Under Database, choose PostgreSQL.
- Pick a free site name under Site address if you like, then create the project.
The platform creates the database and puts the connection settings, such as DATABASE_URL, into the project's App settings tab for you. There's no database password to copy anywhere.
Step 2: Give the link and token to your AI
After the project is created, the screen shows a ready-made message for your AI containing the connection link and the project's token. Copy all of it, open an empty folder on your computer with your AI, and paste the message as the first thing you send. The AI reads the BrewInTH guide and learns which database the project has and how to deploy it.
The token expires after a while. If you continue another day and it has expired, go to AI connections, create a new token and give it to the AI in the same chat.
Step 3: Have the AI plan the app and design the table
Ask for a plan before any code, so you can check you both mean the same thing.
(paste the ready-made message from BrewInTH here)
Please build an "income and expense book" for a small shop with Next.js (App Router,
TypeScript) + this project's PostgreSQL on BrewInTH. Use Prisma via DATABASE_URL.
No pages yet — for now I only want:
1. A page plan: /login, / (this month's entries + totals), /new (add an entry), /export (CSV)
2. schema.prisma: an Entry table (id, date, kind: income|expense, category, amount as an integer
in satang, note, createdAt) and the first migration
3. Sign-in with a single password from ADMIN_PASSWORD and a cookie signed with AUTH_SECRET
(both will be set in BrewInTH's App settings; never in the code or in an uploaded .env)
Show me the plan first and wait for my OK.
Why store amounts as satang (whole numbers)? Decimal numbers in computers can round oddly — 0.1 + 0.2 isn't always exactly 0.3. Storing whole numbers and showing them as baht is safer for money.
Step 4: Write the pages and test locally
Once the plan looks right, let the AI carry on:
The plan is fine, go ahead:
- All four pages, easy to use on a phone: big buttons, amounts with thousands separators, in baht
- Monthly totals: income, expenses, balance; earlier months selectable
- Validate the form on the server too (amount above 0, a valid date)
- Every page that reads the database must render on request (export const dynamic = "force-dynamic"),
because there is no DATABASE_URL during the build on BrewInTH
- package.json: "build": "prisma generate && next build" and "start": "next start"
If PostgreSQL or Docker is available on this machine, test against a local database first.
If not, tell me and we'll test on the live site after deploying.
The line about rendering on request is the most important one in this article. Next.js tries to build pages ahead of time during the build. If such a page reads the database, the build fails on BrewInTH, because builds run on a separate build machine that has no App settings values and cannot reach your database.
Step 5: Deploy to BrewInTH

Deploy this site to BrewInTH so it really works:
1. Set ADMIN_PASSWORD (let me type the password myself) and AUTH_SECRET (random, 32+ characters)
in the project's App settings — never in the ZIP
2. Set the release command to npx prisma migrate deploy
3. Send it as a ZIP with package-lock.json, without node_modules, .next or .env
4. Wait until the release is active, then check the live site: sign in, add an entry,
see the totals, download the CSV
5. If it fails, read the release log, fix it and send again until it passes, then give me the link
This is what the BrewInTH build does with a Node.js project:
- Installs dependencies with
npm ci(when there's apackage-lock.json). - Runs
npm run build. - Runs the release command
npx prisma migrate deploywith the new code, before visitors see it. If the command fails, that release fails and the previous version stays live. - Starts the app with
npm start. The platform sets thePORTvariable (8080 by default), whichnext startreads on its own. - Checks that the home page answers (a 200, or a redirect to the login page) within 5 minutes, and only then switches to the new version.
The Release command field is in the project's App settings tab. Your AI can set it with the token, or you can type it in yourself.
Step 6: Check that it really works
- Click Open site for the project, sign in and add two or three entries.
- The Databases page lets you browse the project's SQL tables; your new entries are in the
Entrytable. - The Releases tab shows the release history with each round's log, and the Logs tab shows the running app's log.
- To run a one-off command, such as adding sample data, use the Commands tab › Sandbox commands and click Run command.
Common problems and fixes

| Symptom | Cause | Fix |
|---|---|---|
| The build fails with something like "Can't reach database server" | Next.js pre-renders a page that reads the database | Add export const dynamic = "force-dynamic" to that page |
| The site is up but says a table doesn't exist | Migrations haven't run on the live database | Set the release command npx prisma migrate deploy and deploy again |
| An error says Prisma Client hasn't been generated | prisma generate didn't run before the build | Make the build script prisma generate && next build |
| You're signed out after every deploy | AUTH_SECRET isn't set, or is regenerated at start-up | Set a fixed value in App settings |
| You changed the schema but the table didn't change | The schema file changed but no migration was created | Have the AI run prisma migrate dev locally to create a migration and include it |
Not sure what's wrong? Send your AI: "Read the latest release log on BrewInTH, explain the cause in plain words, and fix it until it passes."
Making the next change
Want a new feature, such as attaching receipt photos or more categories? Just continue in the same chat:
Add a feature to the income and expense book:
- Add a paymentMethod field (cash / transfer / card) to Entry, defaulting to "cash" for existing rows
- Create a new migration with prisma migrate dev (never edit old migrations, never delete existing data)
- Deploy again and check that all the old entries are still there
The key rules: never edit or delete old migrations, and never reset the database on the live site. The release command only runs migrations that haven't run yet, so existing data stays intact. If you want a way back when the AI makes a mistake with your data, consider the Backups add-on (฿99/month), which backs up your database every day.
FAQ
Can I use the Free package?
Yes. Free gives you one project, one database and 256 MB of RAM — enough for a small site used by a few people. But apps on Free sleep after 3 days without a visitor, so the first visitor after that waits a moment. Once you use it every day or have customers, Starter (฿99/month) has 512 MB of RAM and never sleeps by default.
Do I have to use Prisma?
No. Drizzle or plain pg use the same DATABASE_URL; just set the release command to whatever creates your tables.
Do I need to open a port or set a host?
No. next start reads the PORT variable the platform sets, and your app reaches the database through the DATABASE_URL the platform sets.
Can I open the database from a program on my own computer?
The easiest way is to browse tables and run SQL from the Databases page in the console, or have your AI run queries with the token.
Where should uploaded receipt photos go?
Not in the app's folder — it's reset on every deploy. Have your AI turn on the project's persistent storage (/bw-data) and keep them there.
Summary
Next.js + PostgreSQL on BrewInTH starts with a Node.js project and a PostgreSQL database, then the link + token for your AI. Remember three things to get it live in one go: pages that read the database render on request, npx prisma migrate deploy is the release command, and secrets live in App settings — not in the ZIP.
Start your first project for free →
