Facebook released React in 2013, and itâs not an exaggeration to say that it took the web development industry by storm and has completely transformed how we build websites and web applications.
Not only is React an extremely popular and highly adopted JavaScript framework, but React-powered meta-frameworks have also made an enormous impact in the front-end development space. One React-powered powered framework that stands, in particular, is Next.js. It builds upon Reactâs foundation by offering features like Server-side rendering (SSR), file-based routing, middleware, and API routes.
In this article, we will explore React and Next.js in detail, their features, pros, cons, use cases, and differences.
Since Next.js is built on React, this is not an apples-to-apples comparison. However, comparing them will help us better understand their differences and which to use in certain scenarios.
Letâs dive in.
What is React?
React started as an internal tool at Meta (prev Facebook) until they released it to the public in 2013. It is an open-source JavaScript library for building everything from simple user interfaces to large-scale, interactive websites and web applications. React also supports the development of iOS and Android apps with React Native, its cross-platform mobile development framework.
Reactâs impact on the web development industry is undeniable. It has transformed how we build applications and has led to the creation of multiple React-powered frameworks like Next.js, Gatsby, and Remix.
Over 13.8 million websites use React, including Airbnb, Doordash, Lyft, Dropbox, and Zoom.
Features of React
Virtual Document Object Model (DOM)
The virtual DOM is a lightweight copy of the actual DOM, which allows React to update and render components efficiently. Instead of making changes directly to the real DOM, React compares the virtual DOM with the actual DOM and only updates the necessary parts. This makes React fast and efficient, especially for large and complex applications.
JSX syntax
React uses the JSX (JavaScript Syntax Extension) syntax, which allows us to write HTML-like code inside JavaScript files. JSX makes it easier to define and manipulate components, as it combines the power of JavaScript with the simplicity of HTML.
Although many developers initially pushed against JSX because it went against the principle of âseparation of concerns,â people have grown to like or at least operate it over time.
Hereâs a sample of Reactâs JSX code:
function JsxExample() {
const name = "John";
return (
<div>
<h1 clasName="red-herring">Hello {name}!</h1>
<p>JSX allows us to write Javascript and HTML together.</p>
<img
src="image.png"
width="100px"
alt="React Image">
</img>
<button onClick={() => alert('Clicked!')}>
Click Me
</button>
</div>
);
}
export default JsxExample;
Component-based architecture
React allows us to break down user interfaces into small, self-contained components. We can then reuse these components throughout an application. Each React component can have its own state, props, and functionality, making it easy to manage and update specific parts of the application without affecting the whole.
Reactâs component-based architecture enhances code reusability, maintainability, and scalability.
The code snippet below helps illustrate Reactâs modular approach.
// Header.js
export default function Header() {
return (
<header>
<h1>My Website</h1>
<p>Welcome!</p>
</header>
);
}
// Blog.js
export default function Blog() {
return (
<main>
<p>This is the content section.</p>
<article>
<h3>Hello World</h3>
<p>React is great!</p>
</article>
</main>
);
}
// App.js
import Header from './Header';
import Blog from './Blog';
function App() {
return (
<div>
<Header />
<Blog />
</div>
);
}
export default App;
Built-in state management
React provides three built-in state management solutions: the useState
hook for local state, the Context API for global state management, and the useReducer
hook, a more advanced form of useState
.
- The
useState
hook: one of several hooks react offers. It provides a state variable that allows us to track a componentâs state and a function to update said state. - The
useReducer
hook: an alternative touseState
and is particularly useful for managing complex state logic. - The Context API: for creating global states that we can access anywhere in an application. It requires the
createContext
function and theuseState
anduseContext
hooks to function.
Hereâs a simple counter app that uses the useSate
hook for local state management.
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = () => {
setCount(prevCount => prevCount + 1);
}
const decrement = () => {
setCount(prevCount => prevCount - 1);
}
return (
<div>
<button onClick={decrement}>-</button>
<span>{count}</span>
<button onClick={increment}>+</button>
</div>
);
}
export default Counter;
Reactâs built-in state management solutions may be inadequate for large-scale apps with multiple states that must be in sync with user interactions and UI changes. We can use state management libraries like Jotai and Zustand in such cases.
Advantages of React
Performance optimization
React provides several techniques for optimizing the performance of applications to make them faster and more responsive, including:
- Virtual DOM: As mentioned earlier, the VDOM ensures efficient updates and rendering
- React.memo: A higher-order component that wraps around other components to memoize them and prevent unnecessary renderings
- Lazy loading: It defers loading a componentâs code until it is rendered for the first time
- Suspense component: allows us to show fallback content (e.g., a loading indicator) while its children components are loading
Rich ecosystem
React has a large and active community of developers, meaning there is a wealth of resources, libraries, and support that help us develop applications more effectively and extend their functionality.
Reactâs community has created tools like Framer Motion, Jotai, Next.js, Chakra UI, and Remix. In fact, there are few scenarios where you wonât find a third-party solution for your project. Check out Awesome React, a collection of great sources in Reactâs ecosystem.
Android and iOS mobile app development
One of the advantages of being a React developer is that we can apply our React knowledge to create mobile applications using React Native.
React Native is an open-source and cross-platform React-based framework developed by the React team for building iOS and Android apps. This means that we donât need to learn other languages like Flutter or Kotlin to build mobile apps.
Disadvantages of React
Relies on third-party tools
React is a library for building user interfaces, not a framework, meaning that it does not provide built-in solutions for routing, animations, etc.
React's nature of being an opinionated library allows us to integrate our preferred third-party solutions. However, this makes the development process tricky as we have to vet many third-party solutions.
React's dependence on third-party tools also affects developers who get new jobs because they must constantly learn a different tech stack.
Fragmented community
React has a large and active community, which is generally a positive thing. However, this also means that there are multiple libraries, frameworks, and tools built around React, each with its own approach and best practices. This fragmentation can make choosing the right tools and staying updated with the latest trends in the React ecosystem difficult.
React Use cases
Single-page applications (SPAs)
React is well-suited for developing SPAs, which provide a seamless user experience by dynamically updating content without the need for page reloads. With React, developers can create highly interactive and responsive SPAs that offer a native-like feel.
Progressive web apps (PWAs)
PWAs combine the best features of web and mobile applications, providing an app-like experience within a web browser. React can be used to build PWAs that are fast, reliable, and responsive, regardless of the device or network conditions. React's component-based architecture and state management capabilities make it an excellent choice for developing PWAs.
How to get started with React
The React team recommends using one of the React-powered frameworks for new React applications. However, if we want to use just React, we can quickly spin up a new React project with Vite.
First, run the command below to install Viteâs latest version.
npm create vite@latest
After that, give the project a name and select react as the framework.
Next, run the commands below in sequence to navigate into the folder, install the necessary dependencies, and start the server.
cd vite-project
npm install
npm run dev
Are you an agency evaluating solutions for your clients?
Create high-quality sites faster with Prismic. Check out our agency page to learn more about how you can launch faster and make your clients happier with Prismic.
What is Next.js?
Next.js is an open-source React-powered framework for creating performant websites and applications. It was built by Vercel and has grown in popularity since its release in 2016.
A major season behind Next.jsâ rise to fame is its built-in SSR functionality. This allows developers to create fast-loading websites. The SSR feature also makes Next.js an SEO-friendly framework, which is why developers often use it to build blogs and landing pages.
Next.js is widely adopted by many businesses and the developer community. Companies like Loom, Target, TikTok, and The Washington Post use Next.js for their websites.
Features of Next.js
Server-side rendering (SSR)
Server-side rendering allows us to pre-render the HTML on the server and send it to the client. This means that users who visit a Next.js-powered website will see the fully rendered content immediately without waiting for JavaScript to load.
To use SSR for a page, we need to export getServerSideProps
, an async function that the server will call on every request.
Hereâs an example of how this looks in code:
export default function Page({ data }) {
// Rrender data...
}
// This gets called on every request
export async function getServerSideProps() {
// Fetch data from external API
const res = await fetch(`https://.../data`)
const data = await res.json()
// Pass data to the page via props
return { props: { data } }
}
Static-site generation (SSG)
Static-site generation generates HTML files during the build phase, which are then served to the client as static files. This means every page is pre-rendered and ready to be served instantly without the need for server-side processing.
SSG is good for content that doesnât change often, like blogs and documentation. By default, Next.js pre-renders pages using SSG.
Server-side rendering vs. static site generation
Explore this article to learn the differences between server-side rendering and static site generation.
Image optimization
Next.js provides built-in image optimization via a custom image component called next/image. This custom image component is a wrapper around the standard HTML img
element. The only difference is that next/image
automatically handles image optimization, allowing us to focus on other development tasks.
The benefits of the image component include:
- It automatically serves images in next-gen image formats like WebP and AVIF, ensuring optimum performance and fast loading times
- Provides lazy loading and image blur while loading
- Avoids Cumulative Layout Shift (CLS) while rendering the images, leading to better Core Web Vitals (CWV)
- Allows us to serve responsive images by defining custom breakpoints through its sizes prop
Hereâs a sample code of Next.jsâ image component in action.
import Image from "next/image"
import profileImg from "../public/profile.png"
const Profile = () => {
return (
<>
<h1> User Profile </h1>
<Image
src={profileImg}
alt="user profile image"
width={300}
height={300}
loading="lazy"
placeholder="blur"
sizes="(min-width: 60em) 24vw, (min-width: 28em) 45vw, 100vw"
/>
</>
)
}
Prefetching
Prefetching is a feature of Next.jsâ routing and navigation system, and it is built into the custom Link component. Once a route is inside the viewport, Next.js automatically starts loading the resources for that route in the background.
This means that when a user finally clicks on a prefetched route, the route will load faster because the necessary resources are already available.
Font optimization
Next.js provides a font package, next/font
, which automatically optimizes fonts and eliminates external network requests for improved privacy and performance. The next/font
package works with Google, custom, and local fonts.
Benefits of next/font
include:
- Automatic font optimization
- Improves website performance
- Supports Google fonts and local font
- Built-in automatic self-hosting for font files, which eliminates layout shift
Hereâs a sample code of next/font
in action.
import { Inter, Roboto_Mono } from "next/font/google"
export const inter = Inter({
subsets: ["latin"],
display: "swap",
})
export const roboto_mono = Roboto_Mono({
subsets: ["latin"],
display: "swap",
})
export default function RootLayout({ children }) {
return (
<div>
<h1 className={inter.className}>Styled with Inter font</h1>
<h1 className={roboto.className}>Styled with Roboto font</h1>
</div>
)
}
Script optimization
Next.js provides a next/script
package for loading third-party scripts. The package optimizes scripts by ensuring that scripts only load once, even if a user navigates between multiple routes.
next/script
provides the following script loading strategies:
beforeInteractive
: Load the script before page hydration occurs and before any Next.js code loadsafterInteractive
: Load the script after some page hydration occurs. This is the default strategylazyOnload
: Load the script later while the browser is idleworker
: Load the script in a web worker. This strategy is still experimental
Hereâs a sample code for next/script
:
<Script
src="https://product-gallery.cloudinary.com/all.js"
type="text/javascript"
strategy="beforeInteractive" //this has to be the strategy
/>
Route Handlers
Route Handlers are functions that allow us to handle HTTP requests, run server-side code in our application, and perform tasks like fetching data from a database, handling user authentication, or integrating with external APIs.
Route Handlers support all of the major HTTP methods like GET
and POST
. To use Route Handlers, we must define them in a route.js
file inside the app
directory:
export async function GET() {
const res = await fetch('https://data.mongodb-api.com/...', {
headers: {
'Content-Type': 'application/json',
'API-Key': process.env.DATA_API_KEY,
},
})
const data = await res.json()
return Response.json({ data })
React Server Components
React Server Components (RSC)Â allows us to create async components that get pre-rendered on the server and sent to the client as reusable, interactive units.
Like regular React components, Server components can import client components, render them, and pass data to them through props. However, client components cannot import server components. This means that it's better to place server components at the top of the component tree.
With RSC, components are near the data source. This eliminates trips between unnecessary client-server trips and speeds up operations like data fetching and database mutations.
Note that server components cannot access the browser or cannot perform client-side operations. This means we can't use hooks like useState
and useEffect
.
Hereâs a sample code of RSC in action.
import { getProductsFromDB } from './services/mongo'
export default async function Products() {
const allProducts = await getProductsFromDB.find();
return (
<>
<h1>Products</h1>
{data.map((product) => (
<div key={product.id}>
<h2>{product.title}</h2>
<p>{product.description}</p>
</div>
))}
</>
)
}
Strictly speaking, RSC is a feature of React.js. However, it requires a server system like Next.js provides. Thatâs why weâre covering it under Next.js.
Advantages of Next.js
Improved performance
By implementing SSR, Next.js generates HTML on the server and sends it to the client, resulting in faster page loading times. This is especially beneficial for content-heavy websites or applications that require frequent data updates.
Besides SSR, Next.jsâ built-in image, script, and font optimization features further improve performance.
SEO-friendly
Next.jsâ SSR capabilities make it SEO-friendly. SSR enables search engines to crawl and index the content of our websites effectively, leading to better search engine rankings. This is crucial for businesses that rely on organic traffic to drive their online presence and generate leads.
How Next.js helps with SEO
Want to learn more about how Next.js can improve your SEO performance and help you rank higher on search engines? Explore our article that goes into this subject in greater detail.
Code splitting
Next.js enables automatic code splitting, which loads only the necessary JavaScript code for each route. This feature improves performance by reducing the initial load time, ensuring users get a fast and seamless experience, regardless of their device or network conditions.
Great development experience
Next.js offers a great developer experience, improves productivity, and shortens development time by:
- Providing several built-in features like routing, SSR, and resource optimizations, allowing us to focus on more critical tasks
- Offering comprehensive documentation that improves the learning experience
- Providing TypeScript support, which allows us to write type-safe code
As someone who learned Next.js after years of working with React, I was shocked to see how Next.jsâ built-in features streamlined my development experience and helped me become more productive.
Disadvantages of Next.js
No built-in state management
Unlike frameworks like Angular, Next.js does have a built-in state management solution. That means we must use third-party libraries like MobX, Jotai, and Recoil. Configuring and integrating these libraries can further complicate the development process.
Next.js Use cases
Blogs, news websites, and media publications
Next.jsâ built-in SSR support makes it a great choice for blogs, news websites, and media publications because these projects need fast-loading pages and high search engine visibility. It is also an excellent choice for ecommerce websites that require real-time updates.
Also, Next.js integrates seamlessly with headless website builders like Prismic, which allows us to create unique websites that leave a lasting impression on visitors. Prismicâs Page Builder and slices also empower marketers and content teams to launch pages, update content, and run time-sensitive campaigns with minimal dependence on developers.
Marketing Websites and landing pages
Next.js is a great choice for marketing websites and landing pages for the following reasons:
- Leads to fast-loading websites
- Provides greater search engine visibility due to SSR
- Optimizes the loading of third-party libraries like Google Tag Manager, which are important for tracking the analytics and success of marketing campaigns
- Seamlessly integrates with headless solutions, which enables marketers and editors to launch new pages and keep campaign messages up-to-date
Paddle, a billing solution for SaaS companies, used Prismic and Next.js to build its website.
E-commerce websites
The performance and SEO benefits Next.js provides make it a great tool for e-commerce websites. We can use Next.js to offer online shoppers a great user experience while ensuring high conversion rates.
Pairing Prismic with Next.js allows The Container Store to meet its performance and SEO goals, leading to high SERP rankings for tens of target keywords.
Empower your marketing team to release pages quickly!
Sign up for free to see how Prismic lets you build with your preferred tech stack while enabling marketers to create high-performing, on-brand pages independently. Free up your time for the dev work you love!
How to get started with Next.js
First, run the command below in your terminal to install Next.js.
npx create-next-app@latest
After that, configure the Next.js project to fit your development workflow.
After that, configure the Next.js project to fit your development workflow.
Next, navigate into the projectâs directory, start the dev server, and start building!
cd name-of-project
npm run dev
Ready to start building with Next.js?
Create a free Prismic account to start building with Next.js and Prismic, or kick-start your project with these 9 great Next.js boilerplates you can use for your next project.
Differences between React and Next.js
Library vs framework
One of the key differences between React and Next.js is that React is a JavaScript library, while Next.js is a full-fledged framework.
As a library, React handles only the view layer of an application. It focuses on the user interface and updates it as users interact and perform actions. React is unopinionated and doesn't dictate how we manage other aspects like routing, data fetching, API handling, and testing.
Unlike React, Next.js is an opinionated framework that provides the tools needed to build production-ready apps. It handles routing, server-side rendering, static site generation, image and font optimization, and more out of the box. Next.jsâ opinionated approach reduces decision paralysis and allows us to build faster.
SEO-friendliness
Websites built with React struggle with search engine visibility because React uses client-side rendering. This means that bots and web crawlers index empty HTML shells at the first pass, leading to low SERP rankings.
Building websites with Next.js allows us to enjoy high search engine visibility, thanks to its SSR capability, which allows search engine crawlers to better understand a pageâs content and index it properly.
Optimization features
React provides built-in optimization features like the useMemo hook, memo function, lazy function, and Suspense.
Being a React-based library, Next.js has access to React's optimization features added to the built-in tools it provides, including code splitting, prefetching, and optimization for images, fonts, and third-party scripts. Building websites with Next.js allows us to enjoy the best of both worlds and reduces our dependency on third-party optimization tools and libraries.
Routing
React doesn't provide a built-in tool for handling page navigation and routing. This means that we have to integrate third-party libraries like React Router for navigation in React applications.
Next.js provides a built-in file-based routing system, meaning we donât need external tools. Part of the navigation system is a Link component that prefetches routes, which elevates the user experience by making navigation between pages appear instantaneous to web visitors.
The built-in routing system streamlines the development process, especially for applications that involve multiple pages.
Developer community
React has a larger and more established community than Next.js, one reason being that React was released in 2013, while Next.js was released in 2016. React is one of the most popular JavaScript libraries today, and its developer community constantly releases new third-party solutions, learning resources, and templates.
While Next.js is younger than React, it isnât slacking when it comes to community. Next.js provides a rich developer experience and comes with several amazing features. It is currently one of the most popular React-powered frameworks available. Besides great features, other factors that come into play include:
- Being backed by Vercel
- A solid and well-structured documentation
- A detailed and interactive learning platform
- Developer conferences like the annual Next.js Conf
- A great and active team of developer advocates that constantly engages the community; shoutout to Lee Robinson
TL;DR - React vs. Next.js
Library
Framework
216k
116k
Optimization tools include useMemo
hook, memo function, VDOM, <suspense/>
, and the lazy loading function
Optimization tools include route prefetching, code splitting, and image, font, and third-party script optimization
Conclusion
In summary, React and Next.js both have unique strengths that make them suitable for different projects.
React is a flexible JavaScript library focused purely on building user interfaces, while Next.js is an opinionated framework that builds on React and provides extra functionality like server-side rendering and optimization features out of the box.
When choosing between them, consider factors like the nature of your application, whether SEO is a priority, your team's existing knowledge, and the level of flexibility you need. For marketing sites, blogs, or content-heavy pages where performance and SEO matter most, Next.js is likely the better fit. React may be preferable for complex interactive apps where flexibility and control are critical.
Ultimately, neither is objectively "better" as they aim to solve different problems. Next.js makes it faster to build production-ready apps by providing conventions and pre-built solutions. React offers more customization and control for developers who want to handpick all their dependencies.
Understanding their differences allows us to make informed decisions about which tool to use.
Try editing a page with Prismic
A visual page builder, configured to marketing team's needs. They can easily create on-brand website pages, release more, attract more visitors and convert quality leads.