Let me give a quick overview of modern web dev and maybe the perceived complexity will make more sense. I'll say right right off the bat that you probably don't need to care about 90% of this stuff and you can write raw HTML/CSS/JS, but it may help things make sense.

Ultimately, everything is transformed down into plain old HTML/CSS/JS but there are a bunch of tools we use to make this easier and more stable for users.

---

Let's start with frameworks. You say that "the browser is the UI framework", but it's quite literally not a UI framework. Updating the HTML in a page is extremely tedious. You have to do things like set the innerHTML of elements.

innerHTML: https://developer.mozilla.org/en-US/docs/Web/API/Element/inn...

Frameworks provide an abstraction over these web APIs to all developers to easily update the HTML structure of the page on the fly. An important concept frameworks use is the "virtual DOM", or "vDOM", which is a representation of the DOM (E.g. the page) that is kept in memory. Using a vDOM means you don't have to traverse the DOM tree every time you want to update the page.

DOM: https://developer.mozilla.org/en-US/docs/Web/API/Document_Ob...

If you only have simple effects that only change a few co-located HTML elements a framework won't provide much benefit. However, if you have complex effects that may alter the global state and UI of your app a framework makes it infinitely easier to update UI.

Another benefit of frameworks is Developer Experience (DX). Frameworks use a component model, where you can compose your UI out of multiple components. HTML does not natively support this functionality, so it quickly becomes hard to reason about your page structure. Frameworks also allow developers to do things like selectively render a component without using CSS tricks like `display: none` which styles an element to not appear on the page.

---

Next up is tooling. The tooling ecosystem is quite complex, but luckily these days we mostly don't need to worry about the details.

One of the primary reasons for all the JS tooling is that developers want to write modern JS, but not all users have browsers which support modern JS!

Some users may be on old browsers where modern JS syntax or functions are not implemented and so the page would break. One job of JS tooling is to transpile modern JS or TypeScript (TS) into older JS that is compatible with all browsers.

Another function of tooling is to optimize the HTML/CSS/JS assets. Having large CSS and JS files is not optimal for performance, so JS tooling can automatically minify and chunk assets which makes it more efficient for the browser to load them.

Related to the above, how does our source even end up in a format that is usable for the browser? Our tooling also takes care of that by creating a dependency graph of all our files and external modules then resolving it and bundling everything together (And transpiling it!) into JS code the browser understands.

Node is often involved in tooling because the tools may be written in Node-flavoured JS (Slight differences to browser JS) or you may need a Node process to execute some JS code. However, there are tools that are written in other languages like Go and Rust.

---

Lastly is backend and full stack frameworks like Next.js. This is where Node really matters. Node lets you write JS that can run on a server. It gives you access to things like the file system that are not accessible to JS in the browser.

People often choose to have a Node backend for their JS app because it means they can write JS everywhere, but it's not required. You could have a Java or C# backend and a JS app.

Another reason Node is often used is because it has deep integrations with a lot of frameworks like Next.js so you can co-locate server and client code, and it allows you to write code which is isomorphic, meaning it can run on the server and in the browser.

Some apps require a backend to be deploy because their HTML pages are rendered on the server, like a traditional MVC framework does. Other apps may be purely rendered on the client, in which case you only need to deploy the static HTML/CSS/JS files.

Some newer frameworks will render your components to HTML/CSS/JS pages at build time, meaning you kind of get the best of both worlds. You can use frameworks and the DX that comes with them, but you also get a bunch of generated pages instead of one giant JS app.