Those aren't the things most developers complain about. Most front end developers spend their energy on concerns of code style, tools, build steps, framework madness, state management, and more. Those are fashion concerns. A decent programmer can solve for most of those themselves without external tooling in a fraction of the time and code size, but not everybody that does this work is confident writing original code.
The paradox works like this: If you were capable of writing your own software the triviality of state management becomes self evident. If you are not capable of writing your own software, such as full eternal reliance on some tool set or framework, then the answer doesn't matter.
That’s because most SPAs are duplicating backend logic.
If we kill REST, a lot of the complexity around frontends would be reduced significantly. You don't even need GraphQL or RPC protocols to do that.
I didn't say that it was specifically. REST is still a convention that is usually tied to and influenced by HTTP and its methods. It doesn't necessarily have to be that way exactly, but that's how many web applications are typically written.
> There’s no need to “kill” it.
We don't necessarily need it around either.
> If you’re sure you need another set of verbs and nouns, use http as a tunnel.
That is somewhat along the lines of what I'm suggesting. REST is not necessarily better than an API that just takes POST requests in a way that serves the application's needs directly rather than some abstract standard that homogenizes data in ways that require extra work to be done. For some odd reason, many frontend-oriented developers look at me like I've got bugs crawling out of my ears when I say this, yet the idea of allowing the server to do the bulk of the work is both old and resurging in popularity (e.g. Hotwire, LiveView, HTMX).
However, I think frontend is often quite underrated in its essential complexity. I don't share the opinion that state management is a fashion, it's often tightly intertwined with the UX requirements, which can be varied and have all kinds of difficult essential complexity of their own (often complexity that is under-specified, and up to the programmer to discover).
The lack of experience of many frontend devs, combined with the limitations of dynamically typed Javascript, is a recipe for a lot of very gnarly code. Maybe it would be fair to say that this is self-inflicted, but I am sympathetic. It's quite a difficult problem.
When I think of 'total own-goal', completely pointless self-inflicted hell, I think of Python package management.
Do you know why there are new frameworks, new versions every time? Because web is a moving target. New js/css/html5 features are released every day and the libraries have to update to adopt them.
Back in the day you do not have css variables, so you have either use sass and do all the math inside the preprocessing process, or crazier, using those shitty css-in-js libraries to calculate css properties on the fly. Nowadays you can pass around the variables and it can cover almost all the case. In able to pass the css property to the component, you need to improve your framework.
Another example is html5 history API, back in the old days people implemented link components in SPA with buttons (hilarious but it happened), only after History API is introduced there raised the need to manipulate the history properly, thus another rewrite issued.
before that, ES5 introduced `class`, proving yet another way to write js code, which in some situation make cleaner code than the plain old js functions.
everything in the web is moving, new nice things are introduced every month, if you want to create a modern and performant web application, you need to keep up with the new fancy things, frameworks are no exception for that.
[1]: https://docs.sqlalchemy.org/en/20/changelog/migration_20.htm...
Security support lifetimes make sense for a widely used language or runtime, but not really a frontend web framework on the most backwards compatible language you can have.
I work on frontend right now, but I've worked on backend earlier, as well as gamedev and desktop applications. And it was always like that in every area: when your major dependency has a major version upgrade, you will have to spend effort on migrating your code to support it.
> They seem to have no respect for peoples time or any consideration for longtermism or even just the common decency of backwards compatibility
You mean Svelte 5, the backwards compatible framework that makes all of its new features an optional opt-in? That one?
> What are we at now, React 19?
Allow me to introduce you to the concept of semantic versioning, otherwise known as “a versioning system that has defined meaning”. Any breaking change means a new major version, which is why the numbers increment at a rate that is apparently terrifying. These breaking changes are often absolutely tiny and trivial to adapt to.
I don’t even like React but the upgrade path between major versions is rarely a big deal. You’re taking a non-semantic versioning mindset (new version number? Guess I have to rewrite everything!!) and applying it in a scenario where it doesn’t fit.
There's much bigger topics afoot in the world that also make me think humanity desperately needs better tools to defend & equip ourselves with broadscale collaborative efforts to shut down & reject-by-default negative-valence posts.
The hater-squad has the easiest job on the planet attracting some fellow people who also want to resist learning, change, or who want to feel more secure in their current position. The Dark Side is strong.
Inevitably we will see it in every front-end related thread until the end of time.
For what it's worth, between 2011 and 2016, React shipped versions 0.0.1 to 0.14.0. Then in 2016 they said "fuck it, we're stable now" and jumped immediately to 15.0.0 (they considered 0.14.0 to be mostly equal to 14.0.0).
Then they did 16 in 2017, 17 in 2020, 18 in 2022, and 19 finally in Dec 2024. I don't think 4 major versions in ~9 years is a world breaking amount of churn. I have my problems with the team's development of React, but I think they have a pretty sensible view of breaking changes and limiting churn.
Next time I'll tell you how people used to update their code to use Python 3! Shocky-shocky.
This is absolutely untrue. There's a huge gap in how easy it is to upgrade some stacks vs. others.
Updating dependencies in a language with strong, static types and/or an expressive type system is incredibly easy, for example:
Step 1: update dependencies
Step 2: fix compiler errors
Upgrading major versions of .NET, for example, sometimes requires no work at all.
This is not true in JavaScript, Python, and some other languages where you're only going to discover issues during runtime.
TypeScript makes things a lot better, but you're relying on the authors of your dependencies either using TypeScript or keeping types up to date.
I love types and advocate their use whenever possible. They help a lot but they are a spectrum. Thanks to static analysis tools like TypeScript or even eslint you can get a bit towards automated checks on front end code. Also even compiled languages can miss some things, different languages have type systems that give you different kinds of guarantees. For example, Java has NPEs that can't be caught at compile time.
This I can agree with.
> Updating dependencies in a language with strong, static types and/or an expressive type system is incredibly easy
Java would typically be regarded a pretty close to .NET in regards to its type system, yet I've seen plenty of issues with updating dependencies, whenever you have any sort of dynamic class loading or reflection going on: be it Lombok or MapStruct not liking a specific version of Java, or Spring Boot or one of its many integrations throwing errors during startup after a successful compile, sometimes even disliking specific annotations that worked previously.
A decent type system will help you make sure that the code compiles, sure (and I'm thankful for that), but with some styles of writing code and handling, for example, dependency injection, all bets are off. The same goes for any dependencies that make liberal use of those features. I'd have to dig around for specific examples, but I know for a fact that there are plenty of projects that are stuck on old versions of Spring for that very reason.
Or the fact that there are plenty of pre-.NET Core projects out there that won't be upgraded to anything new anytime soon for similar reasons.
In my experience, updates suck across the board, the only variable is how much. And that applies to everything not just dependencies in code (and runtimes): I've also had seemingly innocuous Debian updates break GRUB and prevent the OS from booting, or even upgrades making exim4 start up for some reason and taking up the port that my mail server needed, preventing it from starting.
Also StimulusJS and htmx are good for simple cases as long as you don't need a global state IMHO.
To give you a simple example.
"What's the best web framework these days for fullstack JS work?"
Ok, Hono, found that. Installed it, great, it even runs well with Bun. Holy shit, it seems like JS is catching up! But now how do I talk to my database? Hono has no such thing, you're on your own.
Ok, let's use Prisma but setting that up there is no one-true-way, it's all blog posts and praying you followed the right one. Also Prisma seems to now work with joins?
Migrations? You set that up manually.
Deploying is another story.
Very painful.
---
Compare to Laravel, Rails or Phoenix. All these things baked in, one blessed paved road to tackle the common things 99.9% of web apps need. We are blessed to have all this great work for free, right at our fingertips. People donated a lot of time and love into building them. I hope javascript one day reaches that level.
It's still cowboyitis out there.
Weird that you went with some framework I've never heard of, and that definitely does not come up when I google for best fullstack JS framework.
> Ok, let's use Prisma but setting that up there is no one-true-way
Maybe the docs? https://www.prisma.io/docs/getting-started
> Deploying is another story.
I mean deployment always brings some complexity, but for the majority of JS frameworks you can get started by building it, throwing it in a docker container, and hosting that somewhere. I don't see what's difficult about that
I've been sitting here as a react developer, quite stagnent in my toolset, using the same React I've been writing since 2015. The 'newest' technology I picked up was Typescript back in 2019.