Our Twitter/X clone gets a memory! In episode 2 of the TanStack Start course we set up PostgreSQL in Docker, model the schema in TypeScript with Drizzle ORM, run the first migration, and seed the database — then verify everything in Adminer and Drizzle Studio.
Everything is written live on screen: the docker-compose file, the typed database client, the users and posts tables, and an idempotent seed script you can run as often as you like.
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
▶️ WHAT YOU'LL LEARN
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
• Why PostgreSQL and Drizzle fit a social app
• Running Postgres + Adminer with one docker compose command
• Keeping secrets in .env (and out of git)
• A single typed database client with drizzle-orm
• Modeling users and posts — unique emails, foreign keys, cascade deletes, self-referencing replies, and indexes
• Why database constraints are your last line of defense
• Migrations with drizzle-kit: generate → migrate
• Writing an idempotent seed script (upsert + insert-if-missing)
• Browsing your data with Adminer and Drizzle Studio
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
⏱️ TIMESTAMPS
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
00:00 Intro — giving the app a memory
00:44 Where the database fits in the request loop
01:06 Relational databases in 30 seconds
01:28 Why PostgreSQL
01:53 Why Drizzle ORM
02:17 Why Docker — one command, same database
02:37 Writing docker-compose.yml (Postgres + Adminer)
03:08 Demo: docker compose up, docker ps & Adminer
04:47 Troubleshooting: when Docker fights back
05:18 Secrets stay out of git (.env)
05:40 One typed database client (src/db/index.ts)
06:04 The data model, one chapter at a time
06:25 The users table
06:52 The posts table — replies via parentId
07:19 Constraints: the last line of defense
07:41 drizzle.config.ts
07:57 Migrations are versioned SQL
08:21 The seed script (src/db/seed.ts)
08:46 Demo: bun db:generate, db:migrate & seeding
11:48 Demo: Drizzle Studio
12:54 Checkpoint & recap — next up: authentication
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
💻 COMMANDS USED
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
docker --version
docker compose up -d
docker ps
bun db:generate
bun db:migrate
bun src/db/seed.ts
bun db:studio
Adminer → http://localhost:8080
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
📦 CODE & RESOURCES
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
Course repository: https://github.com/CarreraPHP/my-tans...
Episode 1 — Introduction & Setup: • Setting Up Production-Ready Social Media w...
TanStack Start: https://tanstack.com/start
Drizzle ORM: https://orm.drizzle.team
Docker Desktop: https://www.docker.com/products/docke...
Adminer: https://www.adminer.org
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
📚 ABOUT THIS SERIES
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
We're building a production-style Twitter/X clone with TanStack Start, React 19, TypeScript, TanStack Router & Query, Drizzle ORM, PostgreSQL, and Better Auth — one focused chapter at a time. Every episode ends with a runnable checkpoint you can commit.
Next episode: Authentication with Better Auth — sign up, login, and real sessions stored in Postgres. Subscribe so you don't miss it!
#TanStackStart #DrizzleORM #PostgreSQL #Docker #TypeScript #React #FullStack #WebDevelopment