Back to notes
April 1, 20267 min read

Why Next.js 16 and Tailwind v4 across the entire VantLabs stack

A decision that looks technical but is really about product: why we standardized VantLabs on Next.js 16 + Tailwind v4 + TypeScript, and what it cost us.

StackNext.jsTailwind

There's a pattern I see in small studios: each product uses a different stack because "that problem needed that tool". It sounds reasonable. In practice, it kills productivity. When you switch projects, your head has to switch mental models: different routing, different types, different conventions, different scripts. What looks like flexibility is accumulated friction.

At VantLabs I made the opposite call: one web stack, opinionated, consistent across every product. Today that's Next.js 16 + React 19 + Tailwind v4 + TypeScript + Postgres + Prisma + NextAuth. Same folder structure, same naming conventions, same commit format. Jumping between the corporate site, ReclamaAI, or the internal dashboard, my head doesn't change worlds.

Why Next.js 16 (and not something else)

I tried alternatives — Remix, SvelteKit, Astro, even going back to Laravel + Inertia. Next.js 16 won for three concrete reasons:

  • Real Server Components. The mental model of "render on the server by default, hydrate only what needs interaction" is exactly how I'd write an app if I could choose. It cuts client bundle brutally without losing DX.
  • Mature App Router. In version 13 it was promising but fragile. In 16 it's robust: nested layouts, route groups, dynamic params as Promise, selective static generation, streaming, suspense. Everything works together without surprises.
  • Vercel, no lock-in. I deploy on Vercel because it's the easiest, but the code doesn't depend on Vercel. If I want to move everything to a Node VPS tomorrow, I can. That freedom matters.

The most controversial part: in Next.js 16, dynamic params are a Promise. This breaks almost every old tutorial, and the first reflex is to complain. After three days with the new API, I prefer it. Forcing await in server components makes it explicit that the page may be streaming data. It's more honest.

Why Tailwind v4 (and not v3)

v4 removes the tailwind.config.js file in favor of an @theme inline block inside your CSS, and at first that sounds like a regression. Configuring Tailwind from CSS? Really?

After migrating three projects: yes, really, it's better. Reasons:

  1. Tokens as CSS variables. My palette lives in tokens.css as native variables. Tailwind consumes them via @theme inline. Result: the same variables work for Tailwind, plain CSS, components with style, and external libraries. One source of truth.
  2. OKLCH as a first-class citizen. The whole VantLabs palette is in oklch(). That gives me perceptual contrast control (impossible with HSL) and dark-mode-friendly mixing with color-mix(). Tailwind v4 supports it without patches.
  3. Faster builds. The new engine (Lightning CSS under the hood) is noticeably faster on medium projects. Not the main reason, but welcome.

What I didn't like about the change

Tailwind v4 still doesn't have an official equivalent to @tailwindcss/typography. I had to write my own rules for blog articles (descendant selectors in a Prose wrapper). It works well and is easier to customize, but it's more code to maintain.

Why we don't use a third-party design system

shadcn/ui is probably the most popular library right now and it's excellent. I use it in ReclamaAI. But for the corporate site I decided not to use it: every component is written from scratch. Why?

  • The corporate site is the public face of the studio. It needs a distinctive look, not a generic one.
  • It's ~25 components. Writing them by hand gave me full visual control and reinforced the design system from the inside.
  • No third-party updates to break. Tomorrow, if I want to change the radius of a button site-wide, it's one file.

The real cost

Unifying the stack has a cost: you give up the freedom to use the perfect tool for each problem. That cost is real. I pay it gladly because the other side — switching projects without switching brains — is worth more for a solo founder.

If VantLabs grew to 5 or 10 people, this decision might not scale. But that day is not today.