My opinion as a web dev who started in the 90s is that you have to follow the history a little bit to know how we got here:

- Serverside rendering (like Rails or PHP) isn't great for clientside interactivity

- The other clientside interactivity frameworks (ActiveX, Flash, Java applets, VBScript, Shockwave, VRML, etc.) all died. (HTMX and Hotwire etc. didn't come until much later)

- So we're stuck with Javascript + XMLHTTPRequest (aka AJAX)

- Vanilla Javascript sucks. It was especially bad back in the day

- jQuery was good for simple DOM manipulations, but hard to make a well-managed codebase around

- Angular came on the scene and it was MUCH cleaner but highly abstracted, and was too much to learn for most people.

- React, a simple UI lib, appeared and quickly took over. Angular became irrelevant. But as a UI lib, React by itself was insufficient for a full app. It had no built-in routing, for example, and syncing server-derived state was difficult to do across pages & components (i.e. something as simple as an app-wide dark mode saved into a user setting on the server wasn't easy to propagate across an app, in the early days).

- Despite all this, the ecosystem around React exploded, and for every problem, there were 100 different half-working solutions. Competing routers, state management libraries, AJAX abstractions, caching layers, even extensions to JS itself (CoffeeScript, Mocha, etc., though of course TypeScript won and made the rest irrelevant).

- There were a lot of problems, and a lot of solutions, so together there were 10 million different React websites, no two of which used the same frameworks. Every project was a chaotic mess made by a mix of junior devs and more experienced devs who still struggled with immature frameworks, builders, and packers, most of which would become obsolete after a year or two.

- Early Next.js made that mess a lot better because it drastically reduced complexity. Instead of offering too much choice like vanilla React + 50 supporting libs did, it chose a few "good enough" presets (typescript, a basic routing system, a SSG/SSR scaffold, SCSS support, a build & pack system, etc.) and packaged all of them into a commercially maintained (but still open source) set of sane defaults abstracted into Next.js major versions. It was kinda like what create-react-app tried to do at first, but more complete and closer to the real-world needs of real-world teams. Ironically it made React a lot more batteries-included, like Angular was, rather than the "just a UI lib" that it was originally supposed to be. This meant that spinning up a new working prototype Next.js site could be done in hours instead of days, and upgrading to new versions could be a once-a-year affair with a Next major version upgrade (assisted by codemods), between supported versions and with a single vendor, rather than separately trying to upgrade your router, build system, packer, linter, etc. – all of which would've been by separate groups, on separate timelines, and half of which would be abandoned. These days Next/Vercel manages that complexity on your behalf so you can just upgrade Next and it will upgrade its own internals, even if, say, they switch from Webpack to esbuild or Vercel's Turbopack under the hood. It made React codebases a LOT easier to work with and maintain. And I think Vercel deserves no small credit in that the post-Next JS landscape looks a lot simpler, with many of the smaller utils falling by the wayside and many of the bigger frameworks copying their approach and being more batteries-included & plug-and-play out of the box now. What used to take 50+ different libs and commands are usually just 1 repo and 1 npm command now. And instead of learning every part of your toolchain separately, you can just holistically learn the "Next" way. It was easier to use, teach, maintain, upgrade, all of it. All in all, Next.js was a drastic improvement in developer experience compared to barebones React.

- But it's possible to overdo this too. Next itself kept getting more complicated as Vercel tried to ramp up their hosting offerings (because they make no money from Next itself, only hosting on Vercel, and when Next was simple enough you could deploy it elsewhere and they'd get nothing). The App Router and React Server Components introduced a lot more mental complexity than the old Pages Router had. Now, with Next 15, they started bundling a prerelease version of React into production Next because Vercel unilaterally decided it was stable "enough", much to the horror of downstream users and intermediary lib maintainers. Now people are moving to other, simpler frameworks again, like Vite or Remix or Astro, which have many of the same benefits of including sane enough defaults (typescript, builders, etc.) but without most of the complexity of Next's extremely powerful (and extremely complicated) hybrid mix of SSG/SSR/serverless/clientside components.

- Next.js is still the best choice IMO if you're building a truly complex, non-Canvas-based frontend with a stateful component tree and you actually DO need/want to manage caching & rendering on a per-component basis. If you do it right, you can optimize the heck out of every part of your component tree, mixing and matching what gets rendered on the server, cached statically on the CDN, and drawn clientside. But very few websites fall into that category. Simpler sites can often be better served by simpler frameworks like Vite or Astro.

- As for "why React", that's really a different question, IMO. Sure, there's HTMX and Svelte and Vue and a bunch of others, but at the end of the day the JS ecosystem is largely a popularity contest, and like it or not, React is the default. It's what people know, it's what companies hire for, it's what third-party libs are made for. If you're an individual or a small team, yeah, use whatever you want, but as a career web dev, React is what pays the bills.