We don't build SPAs. Here's why.
Time to first content
Single Page Application — SPA — works like this: the browser downloads a JavaScript file, runs it, and only then draws the page. Until the script executes, the user sees a blank screen or a spinner. On a fast laptop with a fast connection, this takes fractions of a second. On a mid-range phone on mobile internet — it can take 3–5 seconds. And those 3 seconds are the moment when most people leave.
We build server-first. With Next.js App Router and React Server Components, the server assembles the HTML and sends it to the browser already complete. The user sees real content on the very first response — not a loading state, not an empty block. This is the difference between a First Contentful Paint of 0.4 seconds and 3 seconds. Page interactivity also improves: there's less JavaScript in the bundle because server components simply don't ship code to the client.
There's another benefit that's often overlooked: security. In a classic SPA, all logic runs in the browser — meaning it's visible to anyone who opens DevTools. With server-first architecture, API keys, database queries, and sensitive business logic stay on the server. The client only receives the final result. This removes an entire category of vulnerabilities.
We do use client components where the experience genuinely requires them — complex animations, real-time updates, forms with instant validation. But this is a deliberate choice, not a default. We ask ourselves: does this feature really need to run in the browser? If yes — it becomes a client component. If no — it stays on the server, where it's faster, safer, and simpler.