4 Apr 2026 · 7 min · Engineering
What we changed when we moved to Next 15 RSC
Dino Harbinja
CEO
We moved Starnek's own marketing site to Next 15 + React 19 + Tailwind 4 in early April. Most of it was painless. A few corners surprised us — writing them down so the next person doesn't lose half a Friday to them.
Async params everywhere
Dynamic routes now hand you `params` as a Promise. Awaiting it inside a Server Component is fine, but if you forget the `Promise<…>` annotation TypeScript gets confused and the runtime errors are oblique.
next-intl: hasLocale isn't exported (yet)
We followed the docs and imported `hasLocale` from `next-intl`. It compiled. It crashed at runtime — the helper is in newer versions only. The fix is trivial (`routing.locales.includes(locale as Locale)`), but the error message points at the bundler, not the import.
Lesson
Pin tooling versions per-app, not per-monorepo, when a library is mid-migration. We pinned at 3.22 in package.json and pnpm resolved 3.26.5; 3.26.5 didn't have the export.
Tailwind 4: tokens-as-CSS
Tailwind 4 wants tokens declared in CSS via `@theme`. It's nicer to live in than the JS config — diffs are smaller, dev tooling is faster. The migration path is clean: one `@import "tailwindcss"`, one `@theme` block.
Hot reload of token edits is the part nobody mentioned. It feels like editing a Figma file.