The narrative that frameworks = bad and vanilla js = good falls apart quickly IMHO in medium to large sized projects since the complexity has to be abstracted in some way in order to reach a realistic timeframe for completion.
More pithily, maybe PHP was good, actually?
Popping up a level, this isn't about tools, it's about culture and how we decide to choose. I work every day with teams that need to claw back to sanity from years in the JS fever swamps, and nobody's having a good time when launches are blocked on terrible perf, a11y, etc. The root issues here are down to complexity and eng/management capacity to master it. What gets teams in trouble is picking stacks that have mountains of implicit complexity without attendant controls.
Some of that is captured in this post; hope it helps:
https://infrequently.org/2022/05/performance-management-matu...
Consider that Chrome Dev Tools are built with vanilla js (plus web components). I would call it a medium-to-large-sized project, wouldn't you?
Although Chrome Dev Tools isn't the kind of use case that Alex has in mind when he rants on Twitter. His concern is the mobile web; his reference is a weak Android device (used to be a Moto G4) on a 4g mobile network. Which kinda ignores that there are valid use cases for sites that are built as apps primarily for stationary desktop users.
So, I am not sure exactly what your point is?
We're slowly coming to the realization that none of these platforms are either simpler or faster than what we could do with modern vanilla.
Some very basic things like show/hide images and blocks of text based on user selection require an obscene amount of code/complexity in React that in vanilla is just
element.style.display = condition ? 'none' : 'block'
Bonus is that there's no need to think about component re-render. No need to think about hooks, callbacks, memos, effects, etc. A whole layer of complexity disappears.From a performance perspective, there's no contest. Not only is the resultant JS more performant, having the content actually in HTML at download results in faster renders and time to interactive. Our stats show 90+% of our users are mobile so being fast and light are key parameters.
I think the author's point is that while HTML, JS, and CSS have been advancing, a generation of developers have been invested in React rather than learning the fully capable and often better underlying capabilities of modern browser platforms. There are many, many developers who have been trained in React + component frameworks with only a very cursory understanding of the underlying HTML, JS, and CSS.
Should any team use component libraries or roll vanilla? It depends on the objectives of each team. Often that tradeoff is time to market and future tech debt versus absolute performance. (I have not worked on a React project that didn't have massive tech debt not because of React itself, but the complexity ramp that arises with additional packages, dependencies, state management, and general lack of deep understanding of React's render model).
We still like Astro because it allows us the flexibility to use React (or Vue, or Svelte) in dollops where it makes sense.
In the end I decided to re-evaluate was I was doing, I want make the web better but with React.js I was doing worst the web
That’s just a ternary conditional in React. How is it complex?
Then consider the render model and how it would affect page time to interactive for a large content oriented page.
It’s not perfect. I think we’ll find a better approach eventually, which is why I’m fine with the churn. The churn is part of the search for something better.
I hate the poor UX often produced by React— fat, slow, clunky pages with loading spinners and jank. So, I sympathize with the author. I hope something like Quik gets it’s footing.
But until there’s a better way to build UIs from this subjective developer’s perspective, I’m sticking with React.
People have been building UIs for quite a while now; from before a large percentage of people reading this were born. It's not exactly a new thing. I have generally found building UIs a bit painful in any language, so sure, let's go find a better solution, I'm all for that.
But ... 2 weeks ago I took over a half-finished Go project that's been left to "bitrot" for almost 3 years after the previous developer took a different job. Updating the Go dependencies was pretty easy; updating from 1.4.3 to 1.8.9 and such; maybe 1 or 2 with major version bumps, which were minor incompatibilities. Even the usage of the now-deprecated github.com/golang/protobuf wasn't a big deal, and updating to use the new conventions was boring and unexciting, but fairly painless.
The frontend part ... yikes... Things need to be updated from 3.0.2 to 6.8.4 and nothing works if I update it. There are what seem like to be 500 releases in the meanwhile and a lot of changes to go through. It seems in those 3 years the entire world changed. I spent a day on this, and eventually resigned to just accepting the 100+ security vulnerabilities that npm install throws at me. Most, if not all, probably aren't a huge deal in a browser context, but still...
Certainly from my perspective, there seem to be some problems here. I just want to solve real-world problems and write code, not babysit my 1000+ dependencies for what is actually not a very complex project at all. Of course, you don't deal with any of this for new projects, but a 3 year jump really isn't that long of a period. Some churn is expected, but "yeah, maybe just throw a lot of it away and start from scratch"-kind of churn? Meh.
I’m not going to defend the instability of the rest of the JS ecosystem. It’s totally insane. I try to minimize my deps as much as possible, but even so, they’re in the double digits.
My side project at the moment is a zero-dependency stack.
That said, React itself is pretty stable. My guess is that an upgrade from a 3 year old version would be painless. And I still think React / Preact are the best approach that I’ve found for building UIs. It’s quite painful to go back to templating (ERB or Go templates) by comparison.
There's still a time and place for sending HTML and maybe a few tiny JS files down the wire, but for anything "application-like" it's just not feasible, unless your business is so big and performance matters so much that hundreds/thousands of engineering hours are a valid tradeoff to achieve it.
Regarding data loading and performance, there is a lot of exciting stuff in the near future - Remix loaders, Next.js RFC, React 'use' RFC, Quik, Astro, better bundling/build tools, etc.
I never understood this whole "it is literally impossible to do it without React" (or React alternatives) thing. I've seen it a few times now and it reminds me of 2005 when people were saying it's literally impossible to build any serious program without OOP. I don't really want to have a fight about which approach is "better"; I don't really care, maybe SPAs are better. And if you want to build SPAs then by all means do. If my boss wants me to build an SPA I'll go do it without complaining; maybe not my favourite approach but that's okay. But clearly they're not the only approach that can work well. The insistence that it is, is something I find rather off-putting.
I absolutely think you can do SPAs well; my favourite example is FastMail's web UI, it's pretty good and quite a bit of attention has gone in to various details such as the way the scrollbar/pagination works for large mailboxes. It's just hard to build a good SPA.
I borrowed quite a bit from FastMail's design when we built our own email solution a few years back with a more "classic" server-side templated approach, and I felt the UX was on par, and it was a very manageable project technically.
Are you sure users are really the ones demanding this?
It's more likely that "modern FE" is imposing this additional complexity on itself for other reasons, because most sites are still boring old crud apps that don't need anything "modern". The canonical example is the Todo app, which is...crud.
I don't think it's the users fault.
OK, so what about Vue.js? Or is it dead to you already?
React/Vue/Angular/Whatever are different flavours of the "framework oriented front end development" thing. Yes there differences in both technices and degree you are forced to use only that framework but the principles are essentially the same.
Sadly, they're not what your users want.
For those unaware of the missing context, what he's talking about is how in the 2010s, progressive enhancement — long seen as a webdev best practice — was largely replaced by a JS-first approach by JS frameworks in practice.
It does seem like the JS-first bubble is deflating a bit, but I'm not sure it's on its way to fully popping like the Flash bubble did. I do agree it was a lost decade though. More than a decade. I miss when everyone agreed progressive enhancement was the way to go.
It's entirely possible to build a SPA without abandoning progressive enhancement, but the frameworks do not encourage those best practices. As such, it's rare to see a web app built with a framework that doesn't create a hard dependency on JavaScript or isn't an accessibility disaster.
When I reflect on the last decade of frontend development, the lesson I draw from it is everyone is susceptible to ill-conceived fads, including people who think of themselves as evidence-driven. We're good at convincing ourselves we're objective, especially at times when we're not.
What's really depressing is this tendency applies to all the applied sciences. Tons of people who think of themselves as motivated solely by evidence fall for terrible fads in their field all the time, including, terrifyingly, in areas like medical practices.
I think we'd all do better to spend less time emotionally attaching to our tools and more time looking at evidence and metrics in a dispassionate way. As Paul Graham once said, keep your identities small.
A great book that's vital to grokking this stuff is The Scout Mindset by Julia Galef. She argues we should always just go where the evidence leads. But our monkey brains are bad at this, so it takes a lot of conscious effort or we'll do it poorly. I think JS framework mania is yet more evidence of her thesis.
But many smart people are in different situations in which the best decision is to use a framework.
If I'm Amazon or Google and each ms of time to page load (p99 and average) is measurably worth a 6+ figure sum of money per year, then yes, cutting out the framework and going very very basic is the right thing to do.
If I'm a startup with 3 engineers who need to iterate quickly and don't care about page load time (yet) then I'm going to reach for React.
1. The only reason to cutting out the framework is speed.
There are many reasons to forego a framework. Coupling, maintenance[1], dependencies or simply "keeping it simple" are some of the parameters to take into consideration when choosing for or against a (certain) framework.
More practically: I'm writing a simple job search engine[2]. Plain, vanilla JS, some \<template\> tags, and a library to communicate with the search backend. I dont' yet need anything react-redux-saga-event-based yet. This approach is reaching its limit, but I now have the proper information to make a better choice. I did not have that when I started, so I would've certainly picked the wrong framework and painted myself in a corner there.
2. Without a framework we cannot iterate quickly
As I point out in my blog[1] article, this is has often (but not always) be proven to be exactly opposite. Obviously depending on context and use-case. But there are many situations in which a framework is holding you back. In which it is actually slowing the project down, rather than speeding it up. Frameworks, famously, allow a rapid start, and therefore are great for PoCs, Demos, prototypes, MVPs or even "run-off-the-mill-agency-produce". But over time (think years, decades) often get in the way, hold the project back. Just think of the wasted eons of all engineers "rewriting project P from scratch"; often because it turns out that the current version/market/tech/use requires things that no longer fit the boundaries the framework imposed. Bouddaries welcomed or disregarded when the framework was chosen a decade (or just years) ago.
3. Smaller teams need a framework
See above. But also: what a small team needs is reusable code. Libraries. Not Frameworks per-sé, but libraries. Preferably implemented behind decoupled, isolated layers; away from business-logic. Or, more modern, SAAS, PAAS, IAAS. reusable stuff, preferably implemented behind isolated layers.
[1] https://news.ycombinator.com/item?id=33185010 [2] https://search.flockingbird.social/
I came back to frontend development after a break of 10 years. Back then there was jQuery, CSS and HTML.
I found that the complexity of the tooling had increased 20-fold. All these build and task runners that were cool for a year and then a new one came along.
Those were the costs, but what was the upside? It seems that you can do maybe 10%-20% "more" than back then. It seems to me that this is a very very steep price to pay.
Sure, for my personal projects I am all about KISS but at work, if someone insists we try out this new framework and build a super complicated SPA, why not?
People make fun of resume-driven development but besides the money which obviously is the main benefit of having a job, experience is the other big thing that a job can offer. It is in my best interest that we use the most complex solution. I like the challenge.
Lets be honest, most fronted jobs could be rationalized away and the products would actually be better. It depends on your exact business but in many areas there is not point in keeping your UI "fresh". I have seen lots of redesigns actually HURT sales. Once you have found a design that works for you target customers, just keep riding the good thing.
So yeah, things are insane but as a developer it is neither in my power nor in my interest to change anything.
PMs should be aware of what they bring in when they allow some dev to (re)write the next project to in [this weeks' framework or tech]. PMs can push towards boring, proven and simple tech. Sure, much less fun for devs, might even push away the "magpie-devs" (the ones always chasing the next shiny thing), but in many projects this is probably the best for the business. Not always, but PMs more than devs, should know that any tech has trade-offs and downsides, what they are and how they will affect the business over years and decades.
It's like the blockchain craze that thankfully has passed. A few years ago, any company worth anything had some kind of blockchain project, because "everyone knew" that blockchain was some magic thing that would make your business (and your product) better. Certainly some levels of upper management believed this, and they saw their peers embracing it.
It's the same, but older, for JS-heavy frontends.
The point is that we should carefully re-evaluate how we got here and if we indeed have reaped rewards great enough to compensate for the immense additional complexity.
Am I missing some fundamental new insight?
Better could be "user experience", or "client behavior control/consistency", or ? something. But have we really done side by side comparisons and gathered real evidence?
My instinct is that 80% of websites can be HTML and comfortably meet user needs. Another 15% can sprinkle in a little JS to make some targeted improvements. And finally, maybe 5% really do need full JS frontends.
Our problem in general is that we like shiny new things, clever things, and things which we think will make our developer lives better. But it seems we end up overdoing it, approaching each new thing as if it were a silver bullet.
The Phoenix Framework (LiveView) crowd, and later the Rails (Hotwire) crowd show that you don't need a complex SPA to get user-positive experiences. I have a strong opinion on which of the two does this better and more simply, but that's a separate discussion.
As an aside, for those unaware it may be of interest that Hotwire can be used to incrementally enhance any ecosystem's server-rendered HTML experience and not just Rails. From the simplest option of just including the source but changing absolutely no code, which has an instant impact, to making proper use of it.
One of the projects I use it on is a C# MVC (server-rendered) app and with virtually no effort you get some of the benefits of ye olde update panels from webforms. It's really quite neat.
- modern
- revolutionary
- love ("really really like" is ok)
- can't go back to / can't live without
- is the future
- just (describe which is not)
that's a new one
I understand that some problems are just hard, that there are obstacles, or that things you build don't always turn out to work as well as you intended when you started out (sometimes what seemed like a good idea at the start turn out not to be so good ideas later on), and that many things are also trade-offs where there is no perfect solution. That's all okay. It's the whole attitude I find hard to deal with.
I joined a project using node, npm and angular. Everybody said things like that; "this is so awesome", "JS is great", "never had so much fun".
I tried installing it and needed help at every step, "Oh right! We need to do this in our env because X and Y", "Oh, you missed a step, trust me, it's easier to nuke everything and start again now." I ended up with a 30+ step guide that nobody had documented before. We had a little less than 100 security vulnerabilities.
Almost every standup was an exercise in figuring out some strange problem with node or angular, sometimes several.
This team was definitely doing things poorly, but the unrelenting toxic positivity mixed with the "Rails and Django and Symfony all suck so bad" was hard to take, especially as we struggled to ship a really basic MVP.
I'm sorry, but certain things shouldn't involve participation trophies. Building bird houses with your kids in the backyard, yes. Building anything at least as complex as a toolshed for other people, no. At a certain point (i.e. when our work can have consequences for others), we have to take responsibility for our work, and expect responsibility from others.