Next.js vs. React: A Comparative Tutorial
Discover the differences between React and Next.js, a framework used by companies like TikTok, Hulu, and Nike to supercharge their web apps. Plus: Learn when and how to use Next.js, including rendering, routing, page, and navigation tips.
Discover the differences between React and Next.js, a framework used by companies like TikTok, Hulu, and Nike to supercharge their web apps. Plus: Learn when and how to use Next.js, including rendering, routing, page, and navigation tips.
Ayyaz Ali
Ayyaz is a full-stack developer, founder, and CTO with eight years of experience in a variety of React and JavaScript frameworks. He has deep expertise in handling product builds, and developed an online education platform that has served more than a million students around the world.
Next.js is a lightning-fast React framework trusted by data-heavy streaming sites like Hulu and Netflix. If you’re already versed in React, you should definitely get to know this increasingly popular technology.
Though both React and Next.js help create effective web user interfaces, they have some key differences: Next.js is more feature-rich and opinionated than React. It is especially well-suited for websites focused on search engine optimization (SEO) or pre-rendering.
Next.js vs. React
React, which debuted in 2013, is much more established than Next.js. But the younger framework, released in 2016, is growing in popularity, with more than 113K GitHub stars as of October 2023 and millions of weekly npm downloads. Let’s see a basic Next.js vs. React performance comparison that breaks down when to use Next.js vs. React:
- Development speed: Next.js provides out-of-the-box features that ease the development process for making an advanced React app. With the introduction of its own compiler in Next.js 12, the framework also increased build speeds. Compared to React, Next.js reduces the amount of time an engineer needs to wait for code to refresh, minimizing developer frustration and slowdowns.
- Data fetching and load times: Next.js can traverse the React tree and query for data in the server, allowing for pre-loaded page data. This often results in lower application load times for pages served by Next.js compared to pages written in vanilla React.
- Rendering and SEO: Next.js offers pre-rendering, whereas React uses client-side rendering. Pre-rendered pages enable effective SEO strategies that are challenging to achieve in a plain React app.
- Routing: Next.js provides a structured, predefined file system for routing. Its system offers reduced flexibility compared to React’s various library options (e.g., React Router), but simplifies page setup and routing.
React serves a variety of project types very well, including user dashboards, back-end systems, internal organization tools, and data visualization systems. Next.js is the ideal toolkit with which to enhance React applications that benefit from the power of pre-rendering, including e-commerce stores, social media apps, ticket-booking systems, and education platforms. Let’s explore some of its use cases in more detail, so you can answer the question, “Should I use Next.js?”
Rendering in Next.js
Rendering is the process that converts React code into HTML that the browser then displays as the page’s user interface. Next.js provides three rendering methods—client-side rendering (CSR), server-side rendering (SSR), and static site generation (SSG)—and the added bonus of incremental static regeneration (ISR). ISR combines server-side rendering with a semi-static caching mechanism that relieves server load and provides speeds similar to those achieved by a static site.
Server-side rendering and static site generation fall under the umbrella of pre-rendering, in which HTML pages are generated before being sent to the client side. A great advantage of using Next.js is that it adds powerful support for pre-rendering React apps.
Client-side Rendering
Client-side rendering is the default for vanilla React applications. This method generates the page’s HTML on the client side. In other words, rendering efforts take place in the user’s browser, and JavaScript from the user’s device generates the HTML. The UI appears after the rendering is complete, when the webpage is also interactive (i.e., hydrated).
CSR is possible for Next.js components using React’s useEffect
or useSWR
.
Server-side Rendering
Next.js also enables the generation of a page’s HTML on the server. In this case, the generated HTML is sent to the client so that the webpage’s UI appears before hydration. Then, the viewable webpage is ready for interaction after the client finishes initializing the JavaScript.
On pages where we want Next.js to perform server-side rendering, some simple configuration functions are added to the page.
Static Site Generation
Next.js also offers static site generation, in which all static HTML pages are rendered from the JavaScript at build time. Generating a static site from a React code base requires more upfront build time compared to a React single-page application. However, the payoff here is having static content that can be served and cached at the maximum speed allowed by the site content without the computational overhead of SSR.
We can perform SSG on Next.js pages that we want to generate statically with getStaticProps()
and getStaticPaths()
, the latter of which defines the routes for static pages.
Next.js Search Engine Optimization
Next.js’s speed and ability to pre-render all pages of a website allows search engines to quickly and easily crawl and index the website, improving SEO. SEO is critical for many businesses and websites because websites with better SEO appear higher in search results. Users are more likely to click on higher-ranked websites, with the top result having an average click-through rate of 27.6%, a rate that is ten times greater than the tenth result’s click-through rate of 2.4%.
React websites with large amounts of content—and the resultant JavaScript code used for rendering—face SEO challenges when dealing with Google crawling and indexing.
The ability of Next.js to easily perform server-side rendering (SSR) not only enhances SEO rankings, but also improves a website’s perceived and actual load time for an optimal user experience.
Getting Started With Next.js
Now we’ll look at the essentials of Next.js setup, routing, pages, and navigation so you can reap the benefits of pre-rendering and SEO. Before starting our Next.js tutorial, ensure that you have the latest version of Node.js downloaded on your system. You can verify the Node.js version on your machine with node --version
.
There are two ways to set up a Next.js project:
- Automatic setup, with predefined configurations
- Manual setup and configurations
We’ll follow the automatic setup to get started on our project more easily. The create-next-app
CLI tool manages the automatic setup and makes it possible to quickly build applications. Let’s create our project with the built-in Next.js support for TypeScript, a strict syntactical superset of JavaScript, to ensure proper type structure:
npx create-next-app@latest --typescript
create-next-app
will ask for the name of your application. Your project name must consist of lowercase letters and use hyphens instead of spaces. For example, I’ve named my application next-js-tutorial
. Once setup is complete, you’ll see a success note in your terminal.
In our new project, we can see that Next.js mandates a rigid file structure system:
- The website’s
pages
andstyles
are organized into their own folders. - APIs are stored in the
pages/api
folder. - Publicly available assets are held in the
public
folder.
Next.js Routing and Pages
Next.js uses its file structure inside the pages
directory to define the application routes.
We define all routes in the pages
folder. The default pages/index.tsx
file is the application’s entry point where we define custom fonts, application tracking codes, and other items requiring global access.
There are two methods for adding new routes:
- Add a file ending in
.tsx
directly inpages
. - Add an
index.tsx
file under a new subfolder ofpages
(index
files are automatically routed to the directory root).
Let’s examine a few concrete Next.js examples for routing. We’ll implement a simple page route for our tutorial, then touch on nested and dynamic routing concepts.
Page Routes
We can add a basic page route, such as about-us
, with an about-us.tsx
file:
|— pages
| |— _app.tsx
| |— about-us.tsx
| |— api
| |— index.tsx
Or we can use an index.tsx
file under a pages/about-us
folder:
|— pages
| |— _app.tsx
| |— about-us
| | |— index.tsx
| |— api
| |— index.tsx
Go ahead and add the about-us.tsx
page route to your project.
import styles from '../styles/Home.module.css'
const AboutUs: NextPage = () => {
return (
<div className={styles.container}>
<main className={styles.main}>
<h1 className={styles.title}>
About Us Example Page
</h1>
</main>
</div>
)
}
export default AboutUs
We’ll see page routing in action when we use it in combination with Next.js navigation. For now, we’ll return a placeholder NextPage
with a title string so the navigation will work properly.
Nested Routes
Nested routes allow for multiple layouts to be reused and selectively updated on a page (for example, when a user clicks a URL, you may want to update the body content but preserve the header and footer layouts).
|— pages
| |— _app.tsx
| |— api
| |— index.tsx
| |— parent
| | |— child.tsx
We define the nested route /parent/child
with a parent
folder and a nested child
folder or file (our example shows a file).
Dynamic Routes
Dynamic routes allow layouts to respond to real-time changes in cases where predefined paths do not suffice. Let’s say we want to create a /product/[productId]
route (i.e., when a product is clicked, expand its component). Assuming that productId
is a variable accessible in our definition of Product
, we can easily add a dynamic route by creating a product
folder and wrapping our productId
page in brackets:
|— pages
| |— _app.tsx
| |— api
| |— index.tsx
| |— product
| | |— [productId].tsx
This way, a route like product/testId
will have its query parameters set (i.e., productId
is set to testId
).
Finally, it is also possible to combine routing techniques. For example, we could create the nested dynamic route pages/post/[postId]/[comment].tsx
.
Next.js Navigation
Next.js uses its own custom Link
components instead of the <a>
HTML tag when navigating between client-side pages to allow Next.js to optimize navigation and data pre-fetching. Link
operates similarly to the <a>
tag and uses href
as the route to be opened. You must use the passHref
prop to force Link
to pass its route value to child components (i.e., when using custom-styled components).
The major benefit to using Link
instead of the <a>
tag is that it pre-loads data in the background when a user hovers over or near a link. This makes the content more readily available for the client to process, delivering improved app performance. You may still use the <a>
tag in Next.js when linking to external pages outside of the app.
To link to our About Us page from the Next.js project blueprint, open the pages/index.tsx
main app file. We’ll first import the Link
component from next/link
, and then add a linked paragraph below the <h1>
component:
<p className={styles.description}>
Here's our example <Link href="/about-us">About Us</Link> page
</p>
Now we can run our app using the npm run dev
shell command, visit http://localhost:3000, and see our added text and About Us page working at http://localhost:3000/about-us (the route returned after clicking About Us).
Supercharge Web Apps With Next.js
There are many factors to consider before choosing a framework for your next website. Though Next.js is more opinionated and less flexible than React, the framework offers great out-of-the-box functionality for advanced projects targeting SEO or pre-rendering capabilities. With the foundations of Next.js in your toolkit, you can supercharge your site and get an edge over vanilla React applications.
The editorial team of the Toptal Engineering Blog extends its gratitude to Richard Plotkin for reviewing the code samples and other technical content presented in this article.
Understanding the basics
Why use Next.js?
Next.js makes it easier to build certain web user interfaces, adding features on top of React. It boasts a strong community and documentation, and is gaining popularity among front-end web developers.
Is React better than Next.js?
No, React is not better than Next.js. Developers should choose a framework based on what works best for their project and priorities. (A website focused on SEO might benefit from Next.js, for example, because it reduces app load times.)
Why is Next.js better than React?
Next.js provides improved development speeds, reduced application load times, and pre-rendering.
What is the difference between Next.js and React?
Next.js is a React framework with added out-of-the-box functionality. React is a common JavaScript library used to build interactive user interfaces, especially for web apps.
What problems does Next.js solve?
Next.js provides pre-rendering, and can improve SEO performance with reduced application load times.
Why choose React.js?
React is less opinionated and more established than Next.js, offering developers increased flexibility and extensive resources.
Are React and React.js the same?
Yes, both terms refer to the same JavaScript library.
Is Next.js a framework?
Yes, Next.js is an open-source React-based framework.