Back to path
BeginnerInvoiceDesk · Project 1 of 12 ~3h· 5 milestones

Run it locally and read the request path

You just cloned the InvoiceDesk starter and the README has five bullet points that assume you already know where everything lives.

Docker ComposeNext.js App RouterReact Server ComponentsDrizzle ORMPostgresEnvironment confignext build

What you'll build

You will have the full local stack running (Postgres, Redis, MinIO via Compose, the Next.js app via pnpm dev), a seeded database you can query by hand, and a clear mental trace of one request from browser click to SQL row and back, plus a production build you can compare against dev.

See how we teach, before you sign up

You don't just get code dumped on you. Every starter file and every solution is explained line-by-line, in plain English. Here's one real file from this project:

lib/db.tsts
import { drizzle } from "drizzle-orm/node-postgres";
import { Pool } from "pg";

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
});

export const db = drizzle(pool);

Reading this file

  • connectionString: process.env.DATABASE_URL,this env var is read only on the server, it is never bundled into client JavaScript because lib/db.ts is only ever imported from server components
  • new Pool({a connection pool, not a single connection, so multiple concurrent requests can each get a connection without waiting
  • export const db = drizzle(pool);this is the single db client the whole app imports, both the seed script and every server component use this same instance

Starter file for this rung.

That's 1 of 8 explained code blocks in this single project.

The build, milestone by milestone

  1. 1

    Boot Postgres, Redis and MinIO with Compose

    5 guided steps

    If you skip reading the compose file you will not know which ports, users, and passwords the app expects, and every connection error later will look mysterious instead of obvious.

  2. 2

    Install, configure .env and run the dev server

    5 guided steps

    Every one of these values is a contract between the app process and a container. Get one wrong and you get a connection error whose message rarely tells you which variable is at fault.

  3. 3

    Seed the database and read the schema

    5 guided steps

    You cannot reason about a request trace if you do not know the shape of the data it touches. Reading the schema once now saves you from guessing column names for the rest of the ladder.

  4. 4

    Trace one request end to end

    5 guided steps

    React Server Components blur the line junior developers rely on, where code runs. If you cannot point to the file and line where server code ends and browser code begins, every bug you hit later will cost you an hour of confused debugging instead of five minutes.

  5. 5

    Build it for production and compare

    5 guided steps

    Dev mode hides real startup cost and recompiles on the fly. Understanding the production build now means the deploy rung at the end of this ladder will not be your first encounter with next build.

What's inside when you start

3 starter files, ready to clone
5 guided milestones
5 full reference solutions
8 code blocks explained line-by-line
5 "is it working?" checks
5 interview questions it prepares you for

You'll walk away with

docker compose ps shows postgres, redis and minio all healthy
pnpm dev serves the invoice list at localhost:3000 with seeded rows visible
psql query against invoices returns a nonzero row count
a one paragraph written trace of the /invoices request naming every file and layer it passes through
a working production build started with node .next/standalone/server.js

This is portfolio-grade. Build it free.

Sign up to unlock every milestone step-by-step, the code skeletons, full reference solutions, and checkable tasks, with your progress saved as you build.

Start building