Skip to main content
Frontend

Why I Ditched My React SPA for Next.js (and When You Shouldn't)

Building a React app? Stuck choosing between a separate backend and Next.js? Here's what I learned after shipping both—and how to pick without overthinking.

I remember staring at my editor, coffee cold, wrestling with a CORS error that made no sense. My React SPA was trying to talk to my Node API, and the browser was having none of it. I'd spent an hour on something that should've been trivial. That was the moment I started questioning my default setup: React SPA + separate backend.

Let's be honest: most of us frontend folks default to what we know. We've built components, managed state, and styled until our eyes bleed. But when the boss asks for real-time data, we panic. Suddenly we're neck-deep in server logic, auth tokens, and deployment pipelines.

Here's a scenario that might feel familiar. You're on a small team, maybe two or three devs. You need to build a dashboard that pulls order history from a database. Not rocket science—just a few API endpoints and a UI. The question is: do you keep your SPA and spin up a separate Express server? Or do you migrate to Next.js?

The SPA Shuffle

Option A: Keep your React SPA. You'll add a Node.js API, probably Express, and deploy them separately. Sounds flexible, right? But then you hit the CORS wall. CORS is that HTTP-header dance where your browser asks the server, "Hey, can I talk to you?" And the server has to reply, "Sure, but only from these origins." (MDN Web Docs has a good page on this, but you'll probably read it out of frustration.)

Then there's deployment. You can't just push one project. You've got two: one for the frontend static files, another for the API. Two pipelines, two places to watch for downtime. And if you're the only one who knows both, good luck taking a vacation.

I've seen teams spend a whole sprint just wiring up auth between SPA and API. OAuth flows, refresh tokens—you name it. It's doable, but it's not why you became a frontend dev.

Next.js: The One-Box Solution

Option B: Next.js. You write your React components, and you can also write server-side code—API routes, database queries, all in the same repo. No CORS because your frontend and backend are served from the same origin. That alone saved me hours. And Next.js gives you server-side rendering or static generation out of the box, which can make your app feel snappier.

But here's the catch: Next.js is opinionated. It has its own way of doing routing, data fetching, and deployment. If you need a custom server or a non-Node backend, you're out of luck. And if you've already got a huge SPA codebase, migrating isn't a weekend job.

Numbers Don't Lie (But They're Not Everything)

I once benchmarked a simple CRUD app: Next.js vs. SPA + API. For a basic order history endpoint, the Next.js version had about 40% less boilerplate. That's huge when you're writing it at 2 AM. But for a public API with multiple clients, a separate backend is still the way to go. You can scale it independently, version it, and enforce API keys without mixing concerns.

Let me give you a concrete example. My team needed to expose our product catalog to a mobile app AND a web dashboard. The mobile app needed a different data shape. With a separate API, I could version it and give each client what it needed. Next.js would've forced me into a tight coupling that didn't fit.

Side-by-Side: The Breakdown

What matters Next.js (Full-stack) React SPA + Node API
Code organization One repo for everything Two separate projects
Data fetching Server-side or static generation built-in Client-side fetching with loading states
CORS Not an issue (same origin) You'll configure it, and you'll hate it
Deployment One target (e.g., Vercel) Frontend host + backend server
Backend flexibility Locked to Node and Next.js conventions Any language, any database, any framework
Learning curve for frontend devs Moderate—learn Next.js magic Steep—learn backend concepts, auth, API design

What I'd Do Today

If you're a frontend dev building an internal tool or a startup MVP, and you're not the only one on the codebase, pick Next.js. It's the path of least resistance. You'll get a working app faster, and you can always refactor later if you outgrow it. I've built three projects with Next.js now, and I've stopped missing the separate backend.

But if you're building a public API that others will consume, or you know you'll need non-Node services (like a Python ML model), go separate. You'll save yourself a migration headache down the line.

Here's my quick checklist for Next.js:

  • You're the sole dev or on a small frontend-heavy team.
  • Your backend is simple: CRUD, basic auth, maybe a webhook.
  • You want to deploy to Vercel without thinking about servers.
  • You've spent more than an hour on CORS and feel your sanity slipping.

And if you're still on the fence, try a spike. Build a tiny feature in Next.js for a weekend. See how it feels. You can always go back.

Sources

  • MDN Web Docs (web development) - https://developer.mozilla.org/en-US/docs/Learn_web_development
  • Next.js official documentation - https://nextjs.org/docs
  • MDN Web Docs (CORS) - https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
  • Node.js official documentation - https://nodejs.org/en/docs
  • MongoDB official documentation - https://www.mongodb.com/docs/manual/

Share this article:

Comments (0)

No comments yet. Be the first to comment!