
This is part of a series on the modern web stack, written from a WordPress developer’s seat for people who’ve built on the web for years and still hit stack terms they can’t define. The goal is literacy, enough that you can read any stack list and know what each piece does.
Each post has a 10-15 minute audio companion, generated with NotebookLM, for the gym or the commute.
By now you know what Next.js, React, Drizzle, Supabase, Auth.js, Vercel, GitHub Actions and Tailwind each do, and which WordPress piece each one replaces. What’s missing is the ability to open a real Next.js codebase and follow how they connect: which tool calls which, in what order, and where the secrets live.
This post follows one request from the browser to the database and back, then maps the folders of a typical project to the tools you’ve met.
One Request, From Browser to Database
The scenario: a logged-in user loads their dashboard on a Next.js app with Supabase, Drizzle, Auth.js and Vercel.
- The browser requests
https://app.example.com/dashboard. - DNS resolves to Vercel’s edge network, and the request lands on the nearest node.
- Edge middleware runs, the first of your own code to touch the request. Auth.js checks the session cookie and redirects to
/loginif there isn’t one, before any page renders. - Next.js routes the request to the server component at
app/dashboard/page.tsx. - The server component runs on Vercel’s serverless runtime and calls Drizzle.
- Drizzle sends SQL to Supabase, a network hop from the Vercel region to the Supabase region.
- Postgres returns rows, which Drizzle hands back as typed TypeScript objects.
- React renders the component tree to HTML on the server.
- Vercel streams that HTML to the browser.
- Client components (forms, buttons) load their JavaScript and hydrate.
- A click on a button calls a server action, a server function the client can invoke directly.
- The action runs the same path as steps 5 to 7, triggered by a click instead of a page load.
The WordPress version is Nginx, PHP-FPM, WordPress, MySQL, HTML, browser. Six steps against twelve. The modern path splits the work across more specialized pieces, and you pay for that in complexity. The previous fifteen posts covered what you get back.
What Lives Where
A typical project layout in 2026:
my-app/
├── app/ # Next.js App Router pages
│ ├── (auth)/ # Route group: login/signup pages
│ ├── dashboard/ # Authenticated dashboard
│ │ ├── page.tsx # Server component, queries Drizzle
│ │ ├── loading.tsx # Loading skeleton while page loads
│ │ └── actions.ts # Server actions for this route
│ ├── api/ # API routes (REST endpoints)
│ ├── layout.tsx # Root layout, wraps every page
│ └── globals.css # Tailwind directives + custom CSS
├── components/
│ ├── ui/ # shadcn/ui components (Button, Card, etc.)
│ └── dashboard/ # App-specific components
├── lib/
│ ├── db/
│ │ ├── schema.ts # Drizzle schema (tables as TypeScript objects)
│ │ ├── index.ts # Drizzle client instance
│ │ └── migrations/ # Generated migration SQL files
│ ├── auth.ts # Auth.js configuration
│ └── utils.ts # Shared helpers
├── public/ # Static assets served as-is
├── drizzle.config.ts # Drizzle Kit configuration
├── next.config.mjs # Next.js build configuration
├── tailwind.config.ts # (or CSS-based config in Tailwind 4)
├── tsconfig.json # TypeScript configuration
├── package.json # Dependencies and scripts
└── .github/
└── workflows/
└── deploy.yml # GitHub Actions CI/CD pipeline
Each folder belongs to one tool:
app/is Next.js: routing, server components, server actions, API routes.components/ui/is shadcn/ui, component primitives copied into your repo.lib/db/is Drizzle: schema, client, migrations.lib/auth.tsis Auth.js: session strategy, providers, callbacks.tailwind.config.tsandglobals.cssare Tailwind..github/workflows/is GitHub Actions.
Details vary between repos, but the shape holds, so you can map almost any modern repo onto this list in a few minutes.
Environment Variables: The Glue
WordPress keeps its secrets in wp-config.php on the server. A modern stack needs them in three places.
Local development
.env.local in the project root holds your local Supabase keys, the Auth.js secret and Stripe test keys. It’s listed in .gitignore and never committed.
Vercel
Each project has an Environment Variables panel for production values, and Vercel injects them when functions run. Preview deploys can carry their own set.
GitHub Actions
If CI touches production services, for example to run database migrations during a deploy, those credentials go in the repo’s GitHub secrets.
The same variable usually exists in all three with different values: a local Supabase URL on your machine, a staging URL for previews, a production URL for production.
Three habits keep this manageable:
- Prefix a variable with
NEXT_PUBLIC_only if it’s meant to ship to the browser. Everything else stays server-side. - On a team, use Doppler or 1Password Secrets Automation. Copying values by hand between Vercel’s UI and
.env.localfiles drifts quickly. - Commit a
.env.examplethat documents every variable. A new developer clones the repo, copies it to.env.localand fills in values from the team’s password manager.
The Deploy Flow, End to End
What happens when you push code, covered in detail in CI/CD: Goodbye FTP, Hello GitHub Actions:
- You push a branch to GitHub.
- The workflow in
.github/workflows/deploy.ymlstarts. - CI installs dependencies, type-checks, lints, tests and builds. Any failure stops the pipeline.
- For a pull request, Vercel creates a preview deploy at a unique URL such as
my-app-git-feature-team.vercel.appand posts it to the PR. - You click through the preview and send the URL to the client.
- You merge to main, and CI runs again.
- Vercel deploys to production. The URL switches over atomically, with no downtime.
- Sentry receives a release marker, so errors after this point are tagged with the new version.
- You watch the metrics for ten minutes. If something breaks, one click in Vercel’s dashboard brings the previous deploy back.
Compare that with FTP-ing files and refreshing production to see what broke.
What This Changes for WordPress People
You read repos faster. You know lib/db is where the database lives, and a deploy YAML is a structured version of steps you’d otherwise do by hand.
Your client scoping gets sharper. “Auth.js for login, Drizzle on Neon for the database, Stripe for billing, Vercel for hosting, GitHub Actions for deploys” is a sentence you can say, and then discuss the cost and trade-offs of each piece.
AI coding tools become useful. They write modern stack code well because the patterns are so consistent, and once you know those patterns you can review and direct what they produce. Without that literacy you can’t evaluate the output.
The Cross-Cutting Traps
Region mismatches
Vercel functions in iad1 talking to a Supabase database in eu-west-1 add 100-200ms of round-trip latency to every query. Put the runtime and the data in the same region.
Environment variable drift
A .env.example that no longer matches reality is worse than none. Audit your variables at every release.
Works locally, breaks in production
Local dev runs a long-lived Node process, while production runs cold-starting serverless functions, so server components behave differently. Test on a Vercel preview deploy before merging, not only on your laptop.
Distributed costs
Vercel, Supabase, Sentry, Resend and Clerk make five bills, each with its own free tier and its own way of spiking. Keep a small cost model per project and review it monthly.
Gradual lock-in
Every tool has an escape hatch, and using it is work. Pick tools deliberately and drop the ones that stop paying for themselves, but don’t swap one because it’s trending on X.
Learn It by Reading Code
Reading code is the fastest way to internalize the integration model.
Start with the Vercel templates gallery. Clone a Next.js, Supabase and Drizzle starter and read it end to end. The starters are clean and show the patterns clearly. After that, pick any open-source Next.js SaaS project on GitHub with a sensible structure.
For video, Lee Robinson’s channel and Code With Antonio’s “Build a Full-Stack Next.js App” walk through a real project layer by layer. Theo’s videos on the T3 Stack give a strongly opinionated take on how the pieces fit.
Two docs are worth bookmarking: the Next.js deployment docs, which show what Vercel adds beyond the framework, and the 12-factor app principles, the baseline modern hosting was designed around.
If you came in through the series, the earlier posts fill in each piece: why the modern web feels alien, React in WordPress terms, Next.js, Drizzle and the database layer and auth.
That’s the end of the main course. From here, ship a small Next.js app yourself, hire contractors on this stack and know what to ask them, or move on to the AI dev tooling that this literacy makes useful.

Leave a Reply