In my opinion the complexity is caused by the amount and the combination of technical choices, design choices, and process pipeline choices.
... Long story short is that a web app is cross-platform (browser) program and that very quickly gets quite complicated requirements. Of which security, dependency management and frameworks are a big part. Because you need to know about them, and how they work etc..
Long story / ramble:
A simple static website can be as simple as a bit of HTML with CSS.
But when you introduce workflows and users it isn't long before security comes around the corner. And that introduces a lot of complexity, which frameworks and packages help with. (Don't roll your own)
So the security packages comes with typescript. Which makes you adopt typescript and adds a bit of complexity over JS. (But also typesafety! I'm a fan FYI)
And then you want the website work as a progressive web app, so you need a service worker. More complicated.
You then might want to add some sort of isolation of CSS, or use Sass or some other framework. To help with code re-use and avoid breaking things as the app gets larger. Also more complicated.
Then your PO says you need to have async workflows and let the user know when something starts and is done, with push messages. So you need a background worker and push messages.
And we're not even talking about the technical issues, like not all browsers supporting certain API's or certain styles. Or updates to package X breaking package Y, needing a package patch.
Not to mention keeping up with the evolving syntax and language capabilities. HTML, Javascript, Typescript, CSS, SASS etc... They all keep changing and evolving.
... Long story short is that a web app is cross-platform (browser) program and that very quickly gets quite complicated requirements. Of which security, dependency management and frameworks are a big part. Because you need to know about them, and how they work etc..
Long story / ramble:
A simple static website can be as simple as a bit of HTML with CSS.
But when you introduce workflows and users it isn't long before security comes around the corner. And that introduces a lot of complexity, which frameworks and packages help with. (Don't roll your own)
So the security packages comes with typescript. Which makes you adopt typescript and adds a bit of complexity over JS. (But also typesafety! I'm a fan FYI)
And then you want the website work as a progressive web app, so you need a service worker. More complicated.
You then might want to add some sort of isolation of CSS, or use Sass or some other framework. To help with code re-use and avoid breaking things as the app gets larger. Also more complicated.
Then your PO says you need to have async workflows and let the user know when something starts and is done, with push messages. So you need a background worker and push messages.
And we're not even talking about the technical issues, like not all browsers supporting certain API's or certain styles. Or updates to package X breaking package Y, needing a package patch.
Not to mention keeping up with the evolving syntax and language capabilities. HTML, Javascript, Typescript, CSS, SASS etc... They all keep changing and evolving.