Getting Started with Vela + Codex: Build a Tiny Task Planner
In this tutorial you'll build a small Task Planner app (create tasks, mark done, delete) using Vela for Postgres and Codex as the builder. The key idea: you won't hand-write the app. You'll drive it with a sequence of focused Codex prompts.
Create your Postgres backend in 90 seconds.
Launch a production-ready Postgres stack with branching and instant clones.
Start in 90 secondsWhat you'll end up with
- Next.js app + simple, but powerful UI
- /api/tasks CRUD routes
- Postgres schema + migrations
- A feature DB branch workflow in Vela (schema changes without breaking main) (Vela - Postgres Database Platform)
Prerequisites
- Node.js 22+
- A Vela project (the hosted sandbox is fine)
- Codex available in your environment (ChatGPT / IDE / terminal) (OpenAI Help Center)
Step 0: Create a Vela database and copy the connection string
In Vela Studio:
- Create project:
task-planner - Create branch:
main - Copy the Postgres connection string for
main(Connecting to your database (Vela Docs))
You'll paste it into .env.local later as DATABASE_URL=....
Step 1: Create an empty app folder (then let Codex do the rest)
Create a new folder and open it in your editor:
mkdir task-planner && cd task-planner
git init Now open Codex and run the prompts below in order. Tip: Codex works best when you explicitly ask it to (1) edit files, (2) run commands, and (3) stop to show you what changed. That aligns with OpenAI's own Codex prompting guidance. (OpenAI Developers)
Prompt 1: "Bootstrap the project"
Paste this into Codex:
You are my coding agent. Build a minimal Task Planner web app.
Constraints:
- Next.js (App Router) + TypeScript + Tailwind
- Postgres via Drizzle ORM + drizzle-kit migrations
- API routes under /app/api
- Keep it small and readable (no auth yet)
Tasks:
1) Scaffold the Next.js app in the current folder.
2) Add dependencies: drizzle-orm, drizzle-kit, postgres, zod.
3) Create .env.local template with DATABASE_URL placeholder (do not hardcode secrets).
4) Print the exact commands you ran and a short summary of the file tree.
Stop when done. What Codex should do:
pnpm create next-app …(or npm)- Install deps
- Create
.env.local.example
Prompt 2: "Add DB layer + first migration"
Once the repo exists, give Codex this prompt:
Add the database layer with Drizzle.
Requirements:
- Create src/db/schema.ts with a tasks table:
id (uuid PK default), title (text not null), notes (text nullable),
due_at (timestamptz nullable), done (boolean default false), created_at (timestamptz default now)
- Create src/db/index.ts that reads process.env.DATABASE_URL and exports a Drizzle db client.
- Add drizzle.config.ts pointing to schema and migrations output folder.
- Add package.json scripts: db:generate, db:migrate
- Generate the initial migration and run it.
Ask me to paste DATABASE_URL into .env.local if needed before running migrations.
Then show the migration file created and the final schema. You'll:
- Paste your Vela
DATABASE_URLinto.env.local - Let Codex generate + apply migration
Prompt 3: "Create CRUD API routes"
Now instruct Codex to add the backend endpoints:
Implement CRUD API routes for tasks.
Create:
- GET /api/tasks -> list newest first
- POST /api/tasks -> create {title, notes?, dueAt?} (validate with Zod)
- PATCH /api/tasks/:id -> update {done?, title?, notes?, dueAt?} (validate with Zod)
- DELETE /api/tasks/:id -> delete
Rules:
- Use Drizzle queries (select/insert/update/delete)
- Return JSON and appropriate status codes (201 for create)
- Keep code minimal; no extra abstractions
After implementation, provide curl examples for each route. Prompt 4: "Build the UI"
Now have Codex build a tiny UI:
Build a minimal UI on the home page:
- List tasks
- Add task (input + button)
- Toggle done
- Delete task
Rules:
- Use fetch() to call the API routes
- Keep styling simple with Tailwind
- No extra state libraries
After changes, run the dev server and confirm the page loads. At this point you should have a working task planner.
Step 2: Use Vela the "right" way: branch the database for a schema change
Now we'll do a realistic workflow: add a priority field on a separate database branch.
In Vela Studio:
- Branch from
mainclone a new branchfeature/priorityfrom the top navigation bar, click the arrow right of the branch name and select Clone current branch. - Wait for the branch to be created.
- Copy the
DATABASE_URLforfeature/priority - Replace your local
.env.localwith the branch connection string (Vela - Postgres Database Platform)
Prompt 5: "Add priority on a DB branch (safe migration)"
Paste into Codex:
We are now connected to a Vela database branch: feature/priority.
Add a priority field:
- Schema: tasks.priority integer not null default 3 (range 1..5 enforced in API validation)
- Create and run a new migration
- Update POST/PATCH validation to accept priority
- Update UI to display priority and allow editing (simple select 1..5 is fine)
Afterwards:
- Show the migration SQL
- Run a quick smoke test creating a task with priority 5 This is the core Vela benefit: you can iterate on schema changes without touching main. (Vela - Postgres Database Platform)
Step 3: "Merge" back (your normal workflow)
When you're happy with the feature:
- Apply the migration to
main - Point your deployed environment back to
main - Delete the feature DB branch
That "branch → migrate → test → merge" loop is exactly what Vela is built for. (GitHub)
Prompt 6: "Make it shippable in one go"
Optional final polish prompt:
Polish the app for a tiny demo:
- Add basic empty/loading states
- Add a simple filter: All / Open / Done
- Add minimal error handling for API calls
- Ensure lint passes
Then provide:
- A short README with setup steps (including DATABASE_URL)
- A list of the most important files What you learned
- Codex is great at building end-to-end features when you give it tight constraints and staged prompts. (ChatGPT Codex)
- Vela makes database changes feel like git: branch, test migrations safely, then merge. (Vela - Postgres Database Platform)