React is a tool for building a front end. Next.js serves the same purpose. However, both instruments offer a slightly different set of features. More precisely, Next.js gives you more than React. But it doesn't mean you should choose it every time.
See also why I use Next.js in my projects.
Advantages of React.js
If you don't know what React is, it's an instrument that simplifies the development of web pages. It allows you to build components(thus, separating your pages and UI elements into convenient parts) using an advantageous markup(JSX).
Angular and Vue do the same job with some implementation differences. However, these tools bring us convenience in developing the web.
With React, it's simple to start a project(use create-react-app), and we have a bundler and a compiler. The next step is to run the app with one command. "We got it. It's simple, fine, fine!"
To compare React and Next.js, let's look at what Next allows us to do.
A satisfactory tl;dr would be: "Next.js is React but with more features." Next is a framework that uses React. React is a library that gives you the pros you read above, but also it gives you freedom of choice. You may use a different compiler or bundler, or you may use it in the react-native platform. Also, you choose your set of tools: a routing system, an SCSS compiler(if you need SCSS over CSS), and so on.
Next.js gives you React but with an improved developer experience. You don't need to spend time making the choices. But if you want, you can, of course.
Let's look at the specific benefits of Next over React.
Why care: you don't need to spend time choosing a router. There are many routers for React, and you may not know the best fit for your situation.
Next has the router built-in. You only need to put your pages in the `src/pages` folder. So, the "contact.tsx"(`tsx` is a JSX with Typescript) file will be available as a page at "yourAppAddress/contact". There is dynamic routes support too.
Static pages generation
Why care: if you need static pages for your app(e.g., a landing page that leads to the app), and you don't want to make them dynamic(because of the performance), you'll need to configure a server that will serve HTML pages in addition to your React app.
You can generate static pages with Next.js because it has a built-in server.
Why care: the same thing as above, except that you want to generate a page upon each request.
Static generation outputs the HTML that will be reused on each request. The Server-side rendering method will generate HTML upon each request. The former is recommended because of better performance.
Why care: if you want to fetch data skipping CORS or get data from the database directly from your app or read files, you'll need a server.
Next.js data-fetching methods allow you to do all of that without configuring a server. For example, you can generate a static page using fetching local files at build time. Or, you can request a third-party server omitting CORS because Next has an intermediary - an API server.
Why care: you don't need to think about image optimization. I.e., how to reduce an image size, what format to choose, and how to lazy-load the images.
There are usually two apparent problems with images:
- Image size. I.e., reducing a 3MB JPG into a 40KB Webp.
- Loading them after a page is rendered to reduce the network load.
Next solves these problems for a developer, so they can think about the other parts of the app. All the images inside that use `next/image` will be optimized and lazy-loaded. Also, you may set a loading priority for each of them.
It uses SWC
Why care: you need faster build times.
Next uses SWC, which is, according to their claim, "20x faster than Babel on a single thread and 70x faster on four cores". Such speeds are a good enhancement during build times and "hot" reloading.
Why care: you spend time configuring ESlint.
Imagine you wrote a few lines of code and already have the lint issues warnings.
Built-in TypeScript support
Why care: you want to write in Typescript, but configuring it takes some time.
This feature is a huge dealbreaker for me because configuring Typescript takes time. Sometimes it's merely installing the package(`npm install typescript`), and adding the basic `tsconfig.json`. Still, you need to configure it correctly according to your project needs. Since you have various files in a Next.js project(stylesheets, `public` files, JSX, js), imagine going through them to figure out what can be ignored, what rules(configuration) to add, and then to have to break changes with the framework updates.
Next.js does it for us, yay!
Why care: if you want to store some private information like secrets, API keys, etc., and you don't want to expose them in an app's bundle. You may create a server to pull that data from or use some third-party provider, but it takes time and one more place for your code.
The framework supports `.env` files: create a `.env.local`, add the secrets, and nobody will see them. You may also expose some by prefixing them with `NEXT_PUBLIC_`.
Scripts handling and performance
Next.js can do all of that if you use `<Script>` instead of the standard `<script>`. Also, it can offload the scripts to a web worker using Partytown.
It has a server
Why care: you need a server environment. E.g., to make database queries.
We talked about it in the Data fetching section, but it's a good point to highlight one more time because you may need a server for not data fetching only. For example, maybe you need to do some filesystem-heavy logic and then fetch the results via Next.js API server.
So, why React, then?
Next.js has more features than I described here(those I like personally and wanted to highlight). So, we come to the question of why we need React when starting a new project.
Sometimes, you don't need such a beast for a simple use-case. For example, if you have a single static page and you don't fetch any data. Also, you don't have much dynamic logic. Thus, there's no need to bring all of the mentioned features because you need to learn the framework(though its docs are great) and the resources to support the build overhead. I.e., why configure the Next.js CI process if you can have merely an HTML page?
Choose Next.js for a better developer experience, so you don't need to spend time configuring some tools but coding.