# Next.js Explained: Why It Became the Default React Framework

When I first learned React, I thought I had basically learned how to build a frontend.

Components.

Props.

State.

Hooks.

Routing.

API calls.

Okay…

I can build an application now.

Then I tried building something that felt a little more like a real product.

And suddenly I started asking different questions.

Where should the routing happen?

How do I handle SEO?

Should this page render in the browser?

Can I render something on the server?

How do I fetch data before showing the page?

What about performance?

What about authentication?

What about deployment?

And that's when I started seeing **Next.js** everywhere.

At first I thought:

**Isn't Next.js just React with a few extra features?**

Not really.

React gives you the tools to build user interfaces.

Next.js takes React and puts a larger application architecture around it.

That distinction was probably the first thing I needed to understand.

* * *

# If React Is So Popular, Why Was Next.js Created?

React is really good at one major thing:

**Building user interfaces.**

You can create components:

```jsx
function UserProfile() {
  return <h1>Sahil</h1>;
}
```

You can manage state.

You can respond to user interactions.

You can build complex component trees.

But React itself doesn't try to solve every application-level problem.

As applications grow, you start needing things like:

```text
Routing
Data fetching
Rendering strategies
SEO
Server-side rendering
Code splitting
Asset optimization
Application structure
Deployment
```

You can combine React with other libraries and tools to solve these problems.

That's completely valid.

But eventually you have a collection of decisions to make.

Which router?

How should pages render?

Where should data fetching happen?

How should the application be structured?

Next.js came into this space by giving React developers a more integrated framework.

* * *

# React Wasn't The Problem

I think this distinction matters.

Next.js didn't exist because React was bad.

React solved a different problem.

React basically gives us a way to think about UI as components.

For example:

```text
App
 ├── Navbar
 ├── Sidebar
 └── Dashboard
      ├── Chart
      ├── Stats
      └── Activity
```

That's React's strength.

But a production application needs more than components.

That's where a framework becomes useful.

* * *

# React vs Next.js

![](https://cdn.hashnode.com/uploads/covers/69514a87560e53902880bfd9/8574c9d3-de13-488f-a686-c699b8829fcc.png align="center")

The simplest comparison I use now is:

```text
React
↓
UI library

Next.js
↓
React framework
```

React gives you the building blocks.

Next.js gives you a more complete structure for building and running applications with React.

That can include:

```text
Routing
Rendering
Server-side features
Data fetching patterns
Asset optimization
Application structure
```

So I stopped thinking:

**React vs Next.js**

as if they were competing technologies.

It's more like:

```text
React
  ↓
UI foundation

Next.js
  ↓
React
+
Application architecture
```

That's a much better mental model.

* * *

# Why Client-Side Rendering Wasn't Always Enough

A traditional React application can work like this:

```text
Browser
   ↓
Download JavaScript
   ↓
Run React
   ↓
Render UI
```

This is commonly called **Client-Side Rendering**, or CSR.

It works really well for many applications.

For example:

```text
Admin dashboard
Internal tool
Authenticated application
```

The user logs in and spends most of their time interacting with the application.

But imagine a public product page.

A search engine needs to understand the page.

A user opens the URL.

The application may need data before the useful content appears.

Now the rendering strategy starts becoming important.

And that's where Next.js gives you more choices.

* * *

# Rendering Is Not Just One Thing

This was one of the biggest ideas I had to understand.

There isn't one universal way to render every page.

Different applications have different requirements.

Next.js supports several rendering approaches.

The common concepts you'll hear are:

```text
CSR
SSR
SSG
ISR
```

At first these looked like four acronyms I had to memorize.

Then I started thinking about **when the HTML gets produced**.

That made them much easier.

* * *

# Client-Side Rendering

With CSR:

```text
Request
   ↓
Browser
   ↓
JavaScript
   ↓
React renders
   ↓
UI
```

The browser receives the application and React handles the rendering on the client.

This can be perfectly fine.

For example:

```text
Internal dashboard
Admin panel
Private SaaS application
```

You may not need search engines to index every screen.

You may care more about rich client-side interactions.

* * *

# Server-Side Rendering

![](https://cdn.hashnode.com/uploads/covers/69514a87560e53902880bfd9/fe3106a9-d213-4cb3-be38-2ae12f5fcb76.png align="center")

SSR changes the flow.

Instead of waiting for the browser to build the page from scratch, the server can generate the HTML for the request.

Conceptually:

```text
Browser
   ↓
Request
   ↓
Server
   ↓
Render page
   ↓
HTML
   ↓
Browser
```

This can be useful when the initial page needs to contain meaningful content immediately.

For example:

```text
Product page
Article
News page
Public profile
```

The server can generate the page before sending it to the browser.

* * *

# Static Site Generation

Then there's SSG.

The important idea here is that the page can be generated ahead of time.

Think:

```text
Build time
   ↓
Generate HTML
   ↓
Store output
   ↓
User requests page
   ↓
Serve generated page
```

This can work very well for content that doesn't change for every request.

For example:

```text
Documentation
Marketing pages
Blog posts
Landing pages
```

If the content can be generated ahead of time, there's no reason to rebuild it for every visitor.

* * *

# Incremental Static Regeneration

![](https://cdn.hashnode.com/uploads/covers/69514a87560e53902880bfd9/bb5f94b5-2977-4982-aec1-a75e43785b8b.png align="center")

Then I came across ISR.

This sounded like another complicated Next.js feature.

The simple idea is:

You can use statically generated pages while still allowing them to be updated over time.

So instead of:

```text
Generate once
↓
Never change
```

you can think:

```text
Generate
↓
Serve
↓
Eventually regenerate
↓
Serve updated version
```

This can be useful when content changes periodically but doesn't need to be generated from scratch for every request.

* * *

# Why Do We Need Multiple Rendering Strategies?

This was the real question.

Why not just choose one?

Because applications have different requirements.

Imagine:

```text
Homepage
Product page
Dashboard
Blog
Admin panel
```

They don't necessarily need the same rendering strategy.

A public marketing page might benefit from pre-rendered content.

A private dashboard might be heavily client-driven.

A frequently changing page might need server-side data.

So the useful question isn't:

**"Which rendering strategy is the best?"**

It's:

**"Which rendering strategy makes sense for this page?"**

That mindset helped me understand Next.js much better.

* * *

# File-Based Routing

![](https://cdn.hashnode.com/uploads/covers/69514a87560e53902880bfd9/16617058-f021-4c9d-a65a-7e8245dd35e2.png align="center")

Then there's routing.

In a plain React application, you might use a routing library and define routes in code.

For example, conceptually:

```text
/
/about
/products
/products/:id
```

Next.js takes a different approach.

Your file structure can define your routes.

For example:

```text
app/
├── page.tsx
├── about/
│   └── page.tsx
└── products/
    └── page.tsx
```

Now the folder structure itself communicates the application structure.

That's what **file-based routing** means.

* * *

# Why I Liked File-Based Routing

At first, I thought:

It's just a different way to write routes.

But then I opened a larger project.

And the file structure started becoming useful documentation.

You can look at:

```text
app/
├── dashboard/
├── products/
├── settings/
└── users/
```

and immediately understand the major sections of the application.

The routing structure and project structure are connected.

That can make larger applications easier to navigate.

* * *

# Dynamic Routes

What about something like:

```text
/products/123
/products/456
/products/789
```

You obviously don't want to create a separate folder for every product.

Next.js supports dynamic route segments.

Conceptually:

```text
products/
└── [id]/
    └── page.tsx
```

Now:

```text
/products/123
```

and:

```text
/products/456
```

can use the same page structure.

The actual `id` changes.

That's a small feature, but it makes file-based routing much more practical.

* * *

# Nested Routes

You can also create nested structures.

For example:

```text
app/
└── dashboard/
    ├── page.tsx
    ├── users/
    │   └── page.tsx
    └── settings/
        └── page.tsx
```

Now the URL structure naturally follows the folder structure.

```text
/dashboard
/dashboard/users
/dashboard/settings
```

Again…

the filesystem becomes part of the application's architecture.

* * *

# Layouts

Another thing that became useful was layouts.

Imagine an application where every dashboard page needs:

```text
Navbar
Sidebar
Main content
```

You don't want to rebuild that structure manually for every page.

A layout lets you define shared UI around pages.

Conceptually:

```text
Dashboard Layout
      │
 ┌────┼────┐
 ↓    ↓    ↓
Users Settings Reports
```

The shared structure stays in one place.

The page content changes.

That's good for maintainability.

* * *

# Nested Layouts

![](https://cdn.hashnode.com/uploads/covers/69514a87560e53902880bfd9/83cc8248-7be1-4c58-8a6e-9f383f3778a9.png align="center")

The idea gets even more useful with larger applications.

You might have:

```text
Root Layout
   │
   └── Dashboard Layout
          │
          ├── Users
          ├── Reports
          └── Settings
```

Now different parts of the application can have different shared UI.

For example:

```text
Public pages
→ Marketing layout

Dashboard
→ Dashboard layout

Admin section
→ Admin layout
```

This is one reason I started thinking of layouts as an architectural feature rather than just a convenience.

* * *

# The App Router

![](https://cdn.hashnode.com/uploads/covers/69514a87560e53902880bfd9/592b8d4b-ec77-43e4-b100-ace59c58c27e.png align="center")

Modern Next.js applications commonly use the **App Router**.

At first, I thought it was just another routing API.

It's more than that.

The App Router provides a structure around:

```text
Routes
Layouts
Server Components
Loading UI
Error UI
Data fetching
```

The folder structure becomes an important part of the application architecture.

For example:

```text
app/
├── layout.tsx
├── page.tsx
├── products/
│   ├── page.tsx
│   └── [id]/
│       └── page.tsx
└── dashboard/
    ├── layout.tsx
    └── page.tsx
```

Just looking at this already tells me quite a bit about the application.

* * *

# Then I Heard About Server Components

This was probably the concept that made Next.js feel very different from the React applications I had built before.

**Server Components.**

The basic idea is that some components can run on the server instead of being sent as client-side JavaScript components.

Think about:

```text
Server
  ↓
Server Component
  ↓
Data
  ↓
UI
```

The browser doesn't need to execute every piece of application logic.

That can reduce the amount of JavaScript that needs to be shipped to the client.

* * *

# Server Components vs Client Components

![](https://cdn.hashnode.com/uploads/covers/69514a87560e53902880bfd9/be6e833d-e80d-4e5a-b312-4ddf5ffbbc92.png align="center")

A useful high-level distinction is:

```text
Server Component
↓
Runs on server

Client Component
↓
Runs in browser
```

Server Components are useful when a component primarily needs to:

```text
Fetch data
Read server-side resources
Render content
```

Client Components are needed when you need browser-side interactivity.

For example:

```text
Click handlers
State
Browser APIs
Interactive UI
```

So I started thinking:

```text
Does this component need the browser?
        ↓
      Yes
        ↓
Client Component

      No
        ↓
Could run on server
```

That's not the complete decision process, but it's a useful beginner mental model.

* * *

# Why Not Put Everything On The Client?

That was my next question.

If client components work…

why do server components matter?

Because every piece of client-side JavaScript has a cost.

The browser needs to:

```text
Download
Parse
Execute
```

that JavaScript.

If some component doesn't need to be interactive, sending all of that logic to the browser may not be necessary.

Server-side execution can help keep some work on the server.

This is one of the architectural ideas behind modern Next.js applications.

* * *

# Data Fetching

![](https://cdn.hashnode.com/uploads/covers/69514a87560e53902880bfd9/ddd53d0f-bc64-41bf-b21a-bd8846a4b606.png align="center")

Traditional React applications often fetch data from the browser.

Something like:

```text
Component renders
      ↓
useEffect
      ↓
API request
      ↓
Data arrives
      ↓
State update
      ↓
Component renders again
```

This works.

I've used this pattern plenty of times.

But Next.js gives us ways to fetch data on the server as part of rendering the application.

Conceptually:

```text
Request
   ↓
Server
   ↓
Fetch data
   ↓
Render UI
   ↓
Send result
   ↓
Browser
```

That can reduce some of the client-side work.

* * *

# This Doesn't Mean Client Fetching Is Dead

I think this is another area where it's easy to overcorrect.

Just because Next.js supports server-side data fetching doesn't mean every request must happen on the server.

Interactive applications still need client-side behavior.

For example:

```text
Search box
Live filtering
User interaction
Client-side updates
```

The important thing is choosing where the work makes the most sense.

* * *

# Performance Benefits

This is probably where Next.js gets a lot of attention.

But I think it's better to explain the benefits without making unrealistic promises.

Next.js gives developers tools and architectural patterns that can help with:

```text
Initial page loading
Server rendering
Static generation
Code splitting
Image optimization
Reduced client JavaScript
Caching
```

These can contribute to better performance.

But simply installing Next.js doesn't automatically make an application fast.

You can still build a slow Next.js application.

Architecture still matters.

* * *

# SEO

SEO is another reason Next.js became popular for public-facing applications.

A traditional client-rendered application may initially send a relatively small HTML shell and rely on JavaScript to render the meaningful content.

With server rendering or static generation, the server can provide meaningful HTML as part of the initial response.

That can make public content easier for search engines and other crawlers to understand.

Again…

it's not:

```text
Next.js = automatic SEO
```

You still need to build the application correctly.

But the framework provides rendering options that make SEO-friendly architectures easier to build.

* * *

# Next.js Is Not Just About Performance

I think this is important.

If someone asks:

**"Why do companies use Next.js?"**

and the only answer is:

**"Because it's faster."**

that's incomplete.

The bigger benefit is the combination of:

```text
React
+
Routing
+
Rendering
+
Server capabilities
+
Project structure
+
Deployment ecosystem
```

Developers don't have to assemble every piece themselves.

That's a big part of the appeal.

* * *

# When Would I Use Next.js?

There are many situations where Next.js makes a lot of sense.

For example:

### Marketing Websites

You care about:

```text
SEO
Fast initial loads
Static content
```

Next.js fits naturally.

### SaaS Products

You may need:

```text
Authentication
Dashboards
Server-side data
Client interactions
Multiple layouts
```

Next.js can provide a strong foundation.

### E-commerce

You might have:

```text
Product pages
Categories
Search
SEO
Dynamic routes
Server-side data
```

Again, a framework with multiple rendering options is useful.

### Content-heavy Applications

Think:

```text
Blogs
Documentation
News
Publishing platforms
```

Static and server rendering can be very useful here.

* * *

# When React Alone May Be Enough

This is something I think gets skipped too often.

You don't always need Next.js.

Suppose you're building:

```text
Internal admin tool
Small dashboard
Learning project
Simple SPA
```

React alone may be completely sufficient.

If you don't need:

```text
Server rendering
Complex routing architecture
Server-side features
SEO-focused public pages
```

then introducing a full framework may add complexity you don't actually need.

That's okay.

* * *

# Next.js Didn't Make React Obsolete

This is another misconception.

Next.js is built around React.

You still write:

```jsx
function Button() {
  return <button>Click</button>;
}
```

You still use:

```text
Components
Props
State
Hooks
JSX
```

The difference is that Next.js gives those React concepts a larger application environment.

So:

```text
React
   ↓
UI layer

Next.js
   ↓
Application framework
   ↓
React + routing + rendering + server features
```

That is how I think about the relationship now.

* * *

# The Full-Stack React Idea

![](https://cdn.hashnode.com/uploads/covers/69514a87560e53902880bfd9/1dc718c9-3b57-4f05-9ead-a51bef1cd08e.png align="center")

This is probably the biggest shift.

React originally became famous for building the frontend.

Modern Next.js applications can bring more of the application into the same project.

You can have:

```text
Browser
   ↕
Next.js
   ↕
Server
   ↕
Database
```

The exact architecture depends on the application.

But the idea is powerful:

**The frontend and server-side parts can live much closer together.**

That's one reason Next.js became so popular for full-stack React development.

* * *

# The Architecture Started Making Sense

![](https://cdn.hashnode.com/uploads/covers/69514a87560e53902880bfd9/cc8d4085-2a8b-4203-9392-c4242ae9838f.png align="center")

Imagine a SaaS application:

```text
                 Next.js App
                     │
        ┌────────────┼────────────┐
        ↓            ↓            ↓
      Routes       Layouts      Components
        │            │            │
        └────────────┼────────────┘
                     ↓
              Server / Client
                     │
                     ↓
                   Data
                     │
                     ↓
                 Database
```

Now React isn't just responsible for rendering a component.

The framework is helping organize the application around those components.

That's the bigger picture.

* * *

# What Finally Made Next.js Click

I used to think:

**React = frontend.**

**Next.js = React with more features.**

Now I'd describe it differently.

React gives me the component model.

Next.js gives me a framework for building an application around that model.

It helps answer questions like:

```text
Where do my routes live?

How should this page render?

Where should data be fetched?

Which components need the browser?

Which components can run on the server?

How should shared layouts work?

How should the application be structured?
```

And that's why the framework becomes valuable as the application grows.

* * *

# One Thing I Don't Want To Say

I wouldn't say:

**"Next.js is always better than React."**

That's too broad.

There are applications where React alone is perfectly fine.

There are applications where Next.js is a much better fit.

The real question is:

**What does the application actually need?**

If it's a simple client-side application…

React may be enough.

If it's a public application with:

```text
SEO
Multiple routes
Server rendering
Data fetching
Layouts
Full-stack requirements
```

Next.js starts becoming much more attractive.

* * *

# Quick Recap

*   React focuses primarily on building user interfaces.
    
*   Next.js is a framework built around React.
    
*   React-only applications may require additional decisions around routing, rendering, SEO, and application architecture.
    
*   Next.js provides integrated solutions for many of these concerns.
    
*   CSR renders the application primarily in the browser.
    
*   SSR generates page content on the server for a request.
    
*   SSG generates pages ahead of time.
    
*   ISR allows statically generated content to be updated over time.
    
*   File-based routing uses the project structure to define routes.
    
*   Layouts make shared UI easier to organize.
    
*   The App Router provides a modern application architecture around routes and layouts.
    
*   Server Components can execute on the server.
    
*   Client Components are useful for browser-side interactivity.
    
*   Server-side data fetching can reduce some client-side work.
    
*   Next.js can help with SEO and performance, but it doesn't automatically guarantee either.
    
*   React alone can still be the right choice for smaller or client-focused applications.
    
*   Next.js is particularly useful when an application needs a broader full-stack React architecture.
    

That's the foundation.

* * *

# Conclusion

When I first heard:

**"Next.js is the React framework."**

I didn't really understand what that meant.

Now I think of it much more simply.

React gives us a powerful way to build UI with components.

But building a complete application involves more than components.

You need routing.

You need to decide where rendering happens.

You need to fetch data.

You need to think about SEO.

You need to think about performance.

You need a way to organize growing application code.

And eventually…

you need to think about the server too.

Next.js brings many of those decisions into one framework around React.

That's why it became such an important part of the React ecosystem.

But I don't think the lesson is:

**"Always use Next.js."**

The better lesson is:

**"Choose the architecture based on what your application actually needs."**

A small internal tool might not need all of this.

A large public SaaS application might benefit from it a lot.

A blog might care heavily about static generation and SEO.

An interactive dashboard might rely much more heavily on client-side behavior.

Different problems.

Different choices.

And honestly…

that's what made Next.js finally click for me.

It's not just about adding more features to React.

It's about giving React applications a broader structure for the problems that appear when you move from:

**"I'm building a UI."**

to:

**"I'm building a real application."**

If you like this simple learning-style explanation, I write more notes at **devwithsahil.hashnode.dev** and share my progress on LinkedIn 🙂

#nextjs #react #reactjs #javascript #webdevelopment #frontend
