Skip to content

React SPA vs Next.js: How I Stopped Feeling Guilty About My Tech Choices

I kept feeling guilty for not using Next.js.

Every job posting demanded it. The React documentation pushed me toward it. Even my colleagues gave me that look when I suggested Vite for our internal dashboard.

But here’s the thing: our dashboard didn’t need server-side rendering. It didn’t need SEO. It didn’t need edge functions.

I was about to over-engineer a simple CRUD app because of ecosystem pressure.

The Problem: Ecosystem Gaslighting

A recent Reddit thread captured exactly what I was feeling. The original poster said:

“Can we normalize just building a standard React SPA with Vite again without feeling guilty that we aren’t using Next.js?”

This resonated with thousands of developers. The frontend ecosystem has created unnecessary guilt around technology choices.

Here’s what’s happening:

Job Market Reality Your Project Reality
------------------- --------------------
"Must know Next.js" vs "Internal dashboard"
"SSR experience" vs "Behind authentication"
"Edge functions" vs "Simple CRUD operations"

The mismatch is real. But the pressure to conform is stronger.

When I Chose the Wrong Tool

I’ll admit it. I once started a project with Next.js “just in case.”

The project was an admin panel for managing user permissions. Three weeks in, I realized:

  1. I was fighting client/server component boundaries constantly
  2. I had to extract components to “use client” files repeatedly
  3. The caching strategy was adding complexity I didn’t need
  4. Deployments required server infrastructure instead of simple static hosting

The worst part? None of my users were Googling “admin panel for user permissions.” SEO was completely irrelevant.

I had added complexity for features I would never use.

The Decision Framework

After making this mistake, I created a simple decision tree:

Does your app need SEO?
|
+------------+------------+
| |
YES NO
| |
Public content? Auth required?
| |
+--------+--------+ +--------+--------+
| | | |
E-commerce Marketing YES NO
storefront site | |
| | Use SPA Use SPA
Use Next.js Use Next.js
| |
+--------+--------+
|
Performance critical?
|
+-----+-----+
| |
YES NO
| |
Consider Consider
Next.js both fine

Let me break this down with real examples.

When to Use React SPA with Vite

Best for these scenarios:

ScenarioWhy SPA Works
Internal dashboardsNo SEO needed, behind auth
Admin panelsCRUD operations, authenticated users
SaaS applicationsUsers log in, content is private
Personal projectsFast development, cheap hosting
PrototypesQuick iteration, simple deployment

The stack I recommend:

Terminal window
# Create a Vite React project
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install

For data fetching, TanStack Query (formerly React Query) gives you everything you need:

import { useQuery } from '@tanstack/react-query'
function Dashboard() {
const { data, isLoading, error } = useQuery({
queryKey: ['users'],
queryFn: () => fetch('/api/users').then(r => r.json())
})
if (isLoading) return <div>Loading...</div>
if (error) return <div>Error: {error.message}</div>
return <UserList users={data} />
}

Why this works:

  1. Simpler mental model: No client/server component confusion
  2. Cheaper hosting: Deploy to any static CDN (Vercel, Netlify, CloudFlare)
  3. Faster development: No build-time data fetching complexity
  4. Easier debugging: Everything runs in the browser

A developer on Reddit shared this experience:

“Went for React + Vite + TanStack Query, good ol’ React paradigm, worked like a charm. Easier to compose React components compared to Next.js having to extract components because of client vs server.”

When Next.js Actually Makes Sense

I’m not saying Next.js is bad. I’m saying use it when you need its features.

Use Next.js for:

ScenarioWhy Next.js Helps
Public blogsSEO, fast initial load
E-commerceSEO, product pages
Marketing sitesSEO, social sharing
News sitesSEO, content-heavy
DocumentationSEO, static generation

The key feature here is server-side rendering (SSR) for SEO:

// Next.js Server Component - runs on the server
async function BlogPost({ params }: { params: { slug: string } }) {
const post = await getPost(params.slug) // Fetches on server
// This HTML is sent to the client with data already populated
// Google can index it immediately
return (
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
</article>
)
}

When Google crawls this page, it sees the complete content. With a SPA, Google sees an empty div until JavaScript runs.

Next.js also provides:

  • Automatic code splitting (smaller initial bundles)
  • Image optimization
  • API routes for backend functionality
  • Static site generation for fast page loads

These are valuable features for the right use case.

The Real Cost of Over-Engineering

I’ve seen teams suffer from choosing Next.js when they didn’t need it.

Symptom 1: Component schizophrenia

You write a component, then realize it needs state. Now you add “use client”. Then you need to pass data from a server component. Now you’re serializing data or using server actions.

// The complexity spiral
// Server Component
async function Parent() {
const data = await fetchData() // Server-side
return (
// Can't pass functions to Client Component
// Can't use useState here
// Must serialize data as props
<Child data={data} />
)
}
// Client Component
'use client'
function Child({ data }) {
const [state, setState] = useState() // OK here
// But now you're managing two worlds
}

Symptom 2: Cache confusion

Next.js caching is powerful but complex. I’ve seen developers spend hours debugging stale data issues.

Symptom 3: Infrastructure cost

SPAs deploy to static CDNs for pennies. Next.js apps need Node.js servers or edge runtimes.

SPA Hosting Costs (monthly):
- Vercel Free tier: $0
- Netlify Free tier: $0
- CloudFlare Pages: $0
Next.js SSR Hosting Costs (monthly):
- Vercel Pro: $20+
- AWS Lambda: Variable
- Your own server: $10-50+

My Simple Rule

After years of trial and error, I follow this rule:

Start with Vite. Add Next.js only when you can articulate the specific feature you need.

Here’s what that means in practice:

Project Type Start With Add Next.js When...
-------------- ---------- -------------------
Internal dashboard Vite SPA Never (probably)
SaaS application Vite SPA You need public landing pages
Public blog Next.js Immediately
E-commerce Next.js Immediately
Admin panel Vite SPA Never
Marketing site Next.js Immediately

Common Mistakes to Avoid

Mistake 1: Resume-driven development

Don’t choose Next.js because job postings mention it. Choose it because your project needs SSR.

Mistake 2: Future-proofing anxiety

“I might need SSR later” is not a reason to start with Next.js. Migrating from Vite to Next.js is straightforward if you keep your data fetching logic separate.

Mistake 3: Ignoring the basics

Both SPA and Next.js require solid fundamentals:

  • Component composition
  • State management
  • Data fetching patterns
  • Error handling

Master these first. The framework choice matters less than your fundamentals.

Quick Comparison

Feature Vite SPA Next.js
------- -------- -------
Setup complexity Simple Moderate
Deployment Static CDN Server required (for SSR)
SEO Poor Excellent
Initial load JS required HTML ready
Development speed Fast Moderate
Hosting cost Near zero Higher
Component model One paradigm Client + Server
Data fetching Client-side Server + Client

What Actually Matters

The right answer depends on your requirements, not marketing hype.

A developer on Reddit put it perfectly:

“Easy solution is to choose stack based on actual requirements and characteristics instead of hype and marketing. Vite SPA is a good starting point. Couple that with some established backend and you got a cheap, boring and working product.”

Cheap, boring, and working. That’s often exactly what you need.

Summary

Choose React SPA with Vite when:

  • Your app is behind authentication
  • You don’t need SEO
  • You want simpler development
  • You want cheaper hosting
  • You’re building internal tools

Choose Next.js when:

  • You need SEO (public content)
  • You’re building e-commerce
  • You need server-side rendering
  • You want built-in optimizations
  • You have content-heavy pages

The guilt you feel about not using Next.js? Let it go. Use the right tool for the job, not the tool everyone says you should use.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments