React.js is an open-source JS library developed by Facebook for developing User Interfaces (UI's for short). It is one of the most in-demand frontend libraries of today. React breaks the UI elements into reusable components. As the code is being reused, it means the overall code is easier to read, maintain and debug.
That being said, React doesn't do much more than this. To add other functionalities such as module bundling, transpiling, routing, etc. we need to use some other npm packages or ready-to-use frameworks, such as create-react-app (CRA), Next.js and Gatsby. These frameworks provide certain ways of doing things in a more structured way, and they are built on top of React. All three give us a starter project, where certain packages are already installed and ready to go. So as soon as you decide to build a project with React, you are faced with this major decision.
The first thing you need to do is properly understand what your project needs because all three frameworks have their strong and weak points. Also, all of them are constantly changing and growing with many smart people working to improve them. Let's check each of them one by one:
This is probably the easiest one to use if you're creating a Single Page App (SPA). It abstracts away the building process using webpack and transpiles with Babel. For routing and global state management, you might still have to add more dependencies such as react-router-dom and react-redux. CRA generates a single DOM for the whole application, with instructions for how to generate content for all routes. The construction of the pages is done live by the browser instead of the server, so the browser does the heavy lifting. This is called client-side rendering (CSR). Server-side code can be kept simple, and it is completely decoupled with client-side code. But the applications that depend on CSR should consider doing code-splitting and lazy-loading so that they lean on the browser as little as possible.
Next.js uses server-side-rendering (SSR), which means that the application is going to be dynamically rendered on a server, so the server is going to do the heavy lifting. The HTML code that gets generated based on the URL is sent to the client-side, so the SEO is good as the bots can parse it. If you have a website that is constantly changing and needs good SEO, then Next.js is great for that. It also supports static rendering, but it's like driving an F150 Truck in a city, a bit of an overkill.
Gatsby provides static rendering, which means it only creates the HTML code during the build. If you change the data, you have to build it again to see the changes. Gatsby works very well for static websites, such as blogs that load the same way for every user. So one requirement is not to have fast-changing data.
Long story short, the framework you choose to use really depends on your needs and constraints. For the dynamic sites that are rendered slightly different for each user, you can go with either Next.js or CRA. If you need good SEO as well, Next.js is a better choice. If you're building something like an internal business application, for which you won't need the SEO, so CRA is great for you. If your site is going to be static, like a blog, then Gatsby is the way to go. In fact, I also built this blog using Gatsby and I really enjoyed using it. reactjs.org, figma.com, and braun.com are also built with Gatsby. CRA and Gatsby are both supported by static hosting services such as Netlify, so deploying is easier as well.
If you need a more detailed comparison of the rendering methods, check out this article. Good luck and have fun!