Why I Switched from Next.js to Vite + React for Client Projects

TL;DR

After 20+ client projects on Next.js, I switched most of my work to Vite + React. The honest reason: most clients don't need SSR, and Next.js makes you pay for SSR even when you're not using it — in build time, in deployment complexity, in mental overhead, and in money. Vite gives me sub-second dev server starts, smaller bundles, deploy-anywhere flexibility, and a stack a junior can hand off in a week. I still reach for Next.js when SEO, edge rendering, or co-located backend code is genuinely the requirement. The rule I now use is: pick the simplest tool that solves the actual problem in front of you, not the most powerful tool in case the problem grows.

The Tipping Point

I've been a Next.js advocate for years. Server-side rendering, file-based routing, API routes, image optimization, the App Router — it's a powerful framework, and Vercel has done a remarkable job of pushing the web forward through it. For long-form content sites, marketing pages, and large multi-tenant SaaS, it's an excellent default.

But after shipping more than twenty client projects across portfolios, dashboards, admin panels, internal tools, and small SaaS products, I noticed an uncomfortable pattern: almost none of my clients actually needed SSR. They needed a fast app, a clean handoff, cheap hosting, and a stack their next developer could understand without a course.

What they were getting was an SSR-shaped framework that added complexity I had to keep explaining away. The first time I shipped a Vite + React + Supabase project end to end and watched the dev server boot in 200ms and the production build deploy to a static host for free, I stopped pretending. For SPAs, Next.js is overkill, and the overkill has a cost.

The Cost of "Just in Case"

Next.js is built around the assumption that some pages will be server-rendered. Even if you push everything to the client, you're still inside that assumption. You pay for it in:

  • A heavier framework runtime in the bundle
  • A Node.js process at deploy time (or an edge function), instead of a static folder
  • A mental model where every component has to remember whether it's "use client" or not
  • Build times that grow super-linearly with the size of the app
  • A development server that, on a Macbook Air, is noticeably slower
  • None of this is fatal. A lot of it is acceptable for the right project. But for an SPA that's going to live behind auth and ship to a handful of users, every one of those costs is being paid for a benefit that's never collected.

    What Vite Gets Right

    Build speed. Vite's dev server starts in under 300 milliseconds on my machine. Cold start. Next.js takes between 3 and 8 seconds on the same hardware. When you're iterating fast — making a small change, checking the browser, making another small change — that gap compounds into real wall-clock hours over a week of work.

    Simplicity. There is no \`getServerSideProps\