Skip to content
/Next.js vs Vite + React: When to Choose What
Oct 2023·7 min read

Next.js vs Vite + React: When to Choose What

A practical, opinionated comparison of Next.js and Vite + React based on shipping both in production — covering SSR, SSG, bundle size, DX, and the exact decision matrix I now use on every project.

Next.jsViteReactWeb Performance
Text-to-Speech unsupported
Text Size

After building the digital card SaaS platform at The Special Character with Next.js and the admin dashboard at EC Info Solutions with Vite + React, I get this question constantly: which one should I use? Both are excellent choices — the answer depends entirely on what you're building and who visits it.

What Vite is (and isn't)

Vite is a build tool, not a framework. Paired with React it gives you blazing-fast HMR (sub-50ms module replacement vs Webpack's 2–8 seconds), a lean output with excellent tree-shaking, and zero opinions about routing, data fetching, or deployment. For SPAs, dashboards, and admin panels where SEO doesn't matter, Vite wins every time. Our internal EC Info dashboard loads under 1 second — 47kb gzipped JS after manual chunk splitting.

What Next.js is (and the cost)

Next.js is a full React framework with file-based routing, SSR, SSG, ISR, middleware, and built-in API routes. It's opinionated by design. The App Router (Next 13+) introduces server components, which dramatically reduce client-side JS — but also add mental overhead around the server/client boundary. The digital card platform I built hit 95+ PageSpeed scores because Next.js SSG pre-rendered every card as static HTML — zero JS hydration cost on first paint.

Vite manual chunks — splitting vendor bundles
// vite.config.ts
export default defineConfig({
  plugins: [react()],
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          vendor:  ['react', 'react-dom'],
          router:  ['react-router-dom'],
          charts:  ['recharts'],
          ui:      ['lucide-react'],
        },
      },
    },
  },
});
Next.js SSG with ISR — card platform pattern
// pages/card/[slug].tsx
export async function getStaticProps({ params }) {
  const card = await fetchCard(params.slug);
  return {
    props: { card },
    revalidate: 3600, // ISR — revalidate every hour
  };
}

export async function getStaticPaths() {
  const slugs = await fetchAllCardSlugs();
  return {
    paths: slugs.map(slug => ({ params: { slug } })),
    fallback: 'blocking', // generate new cards on demand
  };
}

DX comparison

Vite's DX is unmatched for iteration speed — instant HMR, simple config, and no framework abstractions to fight. Next.js adds complexity: you need to understand when code runs on server vs client, how caching works in the App Router, and when to use server components vs client components. For a team already familiar with Next.js this is fine; for a solo developer building a dashboard it's unnecessary overhead.

Decision matrix

Use Next.js when: the app has public-facing pages that need SEO, you need SSR for personalised content, or you want co-located API routes. Use Vite + React when: the entire app is behind a login (SEO irrelevant), you need maximum iteration speed, or you're building internal tooling. The mistake I see most often is reaching for Next.js by default when a Vite SPA would ship 2× faster and perform identically for the use case.

Rule of thumb: if a Googlebot or social media crawler needs to render your page, use Next.js. If not, use Vite. Don't let framework hype drive architecture decisions — let your SEO requirements drive them.

Share X LinkedIn
NY
Neelesh Yadav
React Native Developer with 3 yr 6 mos years building production mobile apps. Writes about performance, architecture, and mobile engineering.
Follow ↗

Comments

Leave a comment

Comments are reviewed before they appear.

More Articles

Boosting React Native Performance: New Architectures Deep Dive
8 min read
Building Real-Time Chat with WebSocket in React Native
6 min read
AR Try-On: Three.js + MediaPipe in React Native
10 min read