> There was a sad coda; as is the way of contract work, I moved on. I explained what I had built to my replacement, that it always worked even without javascript. He was appalled and said, “but that’s a lot more work for us.”
Why is it more work? The approach described in the article seems honestly reasonably simple: just write the standard <input> components for the form, have a submit button at the bottom. When I was making my own websites many years ago now, that's how it worked, and it wasn't that hard. Maybe it's reflecting my ignorance in this field, but doing fancy front-ends seems much harder to me.
I've found it's enough for most projects.
One of my sites is image heavy and serves 10 TB of traffic per month. For this, I use the following setup:
1. S3 (I wanted reliable data storage) 2. In front of it, I have Cloudflare (with Tiered Cache enabled, which makes POPs prefer pulling from Cloudflare rather than the origin). I've set rules to cache everything on both the browser and Cloudflare for 1 year, ignore origin cache policies, ignore query strings, etc., and I simply use immutable objects that require revisioning. 3. BunnyCDN in front
Cloudflare will not let you run an image heavy site on its own, so I use this approach to massively cut the bills. Their policy says you cannot use it primarily for images; it must be used for HTML, CSS, JavaScript, and other site content.
And if you run only S3, the bills will be huge.
But yes, lately I’ve been building mobile apps. PWAs are limited; the OS can evict IndexedDB storage, so I cannot offer people reliable data storage in the app without sign up or involving a backend.
What can I do? So I was forced to switch to Flutter on Android, but I ran into another pain point: app updates sometimes spend a lot of time "under review," which is frustrating. For the same app, I maintain a web app that is very quick to update by comparison.
I wonder why there isn't a mobile OS that simply lets you build apps with JavaScript, HTML, and CSS and gives you reliable storage without all this effort.
I like how quickly you can update PWA app.
However, I do not like how it is framed as "simple html is better than react" - because you could just as well have told the same story as a react developer.
(Nb. I could go on forever about the complexities and intricacies of storing things session based on a server vs browser based and etc - and lots of other things that were skimmed over in this article, but that would be too long)
All of those things that are simple in html are also simple in react.
It's literally the same code - there's nothing preventing you from using browser based html validation in react - all the same code that gets complicated in react (overly complicated validation logic) also ends up being complicated in astro - they have their own thing around schema validation etc and integrating it within an astro site means you have to integrate their client router etc etc.. so it's very easy to go overly-complicated there as well.
The comparison is also with an off-shore team doing development for you with probably incomplete knowledge and the way projects are structured they have an incentive to create the solution as fast as possible, in as little time as possible, with the biggest amount of complexity as possible.
The last point is devious - it's not necessarily that the contractor does this by design, but the incentive structure makes it so something that's overly complicated actually benefits them, so they don't have a direct incentive to go with something simple.
Anyways, a simple solution, directly addressing the problem at hand is always better - no matter what stack you pick.
(I'd like to say that I don't have anything against Astro's form validation, I was just trying to highlight how there's more to it than "native html browser validation")
Did I miss it, or did the article neglect to explain why this was a problem?
Too much VC money and big tech influence in the JS ecosystem made the web worse in some ways.
Accessibility functions are also helpful; if designed well then it would be helpful for everyone (not only if you are blind or other disabilities), in many possible circumstances.
Yeah, reminds me of the b52 story re holes in wings on the planes that made it back from missions, leading them down the wrong path of strengthening wings. They weren't looking at the planes that never came back with holes in the fuel silages.
https://inavoyage.blogspot.com/2026/06/im-building-parallel-... https://inavoyage.blogspot.com/2026/06/how-about-new-java-ba...
This is the "wonder" that happens when you build for the client instead of for yourself. It takes being truly intentional: sometimes the client (especially that kind of client) does not know what he needs or want; sometimes you as a dev simply build something with good intentions but just out of habit.
Taking the time to ask true, relevant questions, and build backwards, is one of the ways you achieve this. It takes time, energy, intentionality (once again)... but it's worth it.
> Adding a lot of pressure, this was a regulated monopoly
> Some requirements I derived: > ... > We had to meet WCAG accessibility (the team settled on AA rather than AAA)
The author doesn't doxx their employer by giving any dates, but if we take the story at face value and assume it took place in last few years, it is pretty shocking.
How does it take a single hero to be fighting for AA compliance as an afterthought for a project with this scope in the 2020s?
I've worked on much more niche projects that treated this with the respect it deserves as a quasi-legal requirement.
I guess the main argument is how easy it is for an LLM to ingest the content, since I can bet all of the crawlers are llm-enabled one way or another.
Is it more work?
When messing around with my blog's Javascript, this mantra is so thoroughly embedded into writing it, that I try to include "enhance" in function names where it makes sense. I might have to do likewise with my CSS.
Then I start to wonder if that's just because I'm not smart enough to understand React or whatever the fancy technology of the day is.
Feels like I have a hard understanding threshold that cannot be breached - give me a simple editor like Sublime and ask me to make a web page - even with JavaScript - and it's my happy place. Give me VSCode or Zed, Claude/Copilot/ChatGPT plugins everywhere, React tutorials and my brain goes to mush.
OK, I'm still at the beginning and irrelevant to the article, but as a USA-ian, I am so jealous about that. Unheard of here.
https://williamkennedy.ninja/javascript/2022/05/03/in-defenc...
If the creators of React haven't figured it out, what makes you think you can?
Attributing this to the technology driving the browser experience is silly. You can make a brilliant user experience with React. You can make a terrible website with plain HTML.
The improvement comes from the change design, not tech.
> Of course, your javascript-based analytics package doesn’t see the users you are bouncing because of javascript failures.
It is frightening to think of how many people are alienated from critical systems every day because of this bias reinforcing the idea that they do not exist.
Assuming the processor isn't horrible, I can still browse plenty of sites with those specs without much issue, and on the sites that do require more, it's very rarely because the sites actually needs it (i.e. I'm not running Windows XP in a VM in the browser or something). It could just be normal HTML and CSS and normal forms, sprinkled with some light JS to help out a bit. But the amount of sites made with that level of care and attention are sadly rare, since the people responsible rarely feel the pain or have the empathy to fix the problem.
The entire approach went out of style with the advent of single page apps, React, Angular, VueJS, etc.
In this article he recommends the “validation-enhancer” library:
https://www.npmjs.com/package/validation-enhancer
I’ve also seen one called “formisch” that the author of valibot is working on:
https://github.com/open-circle/formisch
They’re both pretty new. Has anyone tried them?
How many such devices can still support modern TLS certificates anyway? By this logic, shouldn't we also use plain HTTP instead of TLS?
Not even that old. 60 year people can't user your fancy site because then don't have an internal model of how a computer works.
You know that when pressing a button a hidden engine runs in the backend (or something runs in the backend). You expect an answer and if the expectation do not match the result, the model in your mind creates an hypothesis about what maybe happened and iterate from there. Maybe you should have clicked something before? Maybe you should mark some form checkbox?
Old people don't have that because they didn't grow up with computers.
What is on the screen is what they see. I clicked next and nothing happens. Well... the site is broken.
You known when you plug your refrigerator and nothing happens and instead of reflecting on the possible blown out resistor that you can bypass with a small wire you understand that your only relationship with the refrigerator is plug and unplug or call for help? That is an old person using your site. They won't fight against it. They'll give up immediately.
While it still does the job, I'm a little curious to explore more modern options, if for nothing else to understand the choices a more junior dev would face/make today.
I'm seriously considering giving Atro a go. Is it worth it?
Back to HN comments it looks like this wasn't actually intentional?
Shipping tens of megabytes per web page is impolite, if not outright disrespectful to users.
> A venerable web application pattern that has had a small modern renaissance thanks to Remix
Remix is not that popular. I don't think attributing this to remix is accurate. Next.js quite possibly.
Our app was fast, and simple, but it also came at a cost: we were limited in our ability to take rich UI elements off the shelf with an npm package. We had to do a lot more work to provide a rich user experience. Everything took longer, and the user experience was worse as a result. We cared, but sometimes you don't have time to carry through.
The company failed, and I don't think react would have saved it. But I can tell you first hand that righteous adherence to "simplicity" didn't help either. It's always a trade-off.
It seems like a lot more work because you have to keep the backend and frontend in closer sync. The backend has to be aware of and able to store every sub-form in the full process (which sounds like a "wizard form" with a multiple sub-forms to get through the full "form" process), not just accept a "finished" or "complete" submission. If a sub-form needs a change the backend, the backend's storage, and the frontend all need to change. The backend and frontend have to agree on validation logic for each small piece of the form. The backend and the frontend need to both validate every small piece of the form, and maybe can't share that validation logic (depending on what language the backend is written in), especially if one of the goals is to do as much of the frontend validation as possible with Browser native validation tools (`<input required` and `<input type="email"` and so forth) so that you get the most benefits of progressive enhancement.
The original ways of making websites were "full stack" and from a full stack perspective it shouldn't seem that hard to have a coordinated frontend and backend, especially when a progressive enhancement approach likely means a smaller more agile frontend, but current siloed world where frontend and backend are different teams with different goals and alignment makes that seem like way too much work.
As someone that reads a lot of code written by others, I'm confident that "learning a new way to do something" is perceived by many as the hardest thing in the world.
The hard part is coming up with a recipe that solves your problem and that the machine can run without breaking things when it runs around with a few billion steps per second. You have to think ahead for it and handle edge cases in the recipe.
That is the really hard part.
Someone is saying that they delivered a very reasonable solution that's simpler than most would come up. Person taking over was not happy.
Do we know if the code being handed over was high quality? Were they reacting to the fact that it was "not React"? Maybe they have a template they enforce in the company about how apps are built?
We don't know.
I'd pee myself in happiness to take over a project like this.
It's not great for every task - in particular the lack of abstraction-building capabilities - but it's great for business-logic-heavy server apps. It feels like it's specialized for that and not trying to be a jack of all trades.
keeping things simple is not a bad thing, and often requires you to be smart enough not to overcomplicate them.
A few of them would outright not know how to do anything else. No knowledge of how to stand up a boring HTTP server to send pure HTML. No experience building a form that validates or submits without JavaScript. These are not the people who post here on HN. They are not engaged in online discussions of new tools and skills (or old tools and skills!). These are people who learned just enough from a bootcamp, or their uni's single "web apps" course, to get a job. Since then, they have just-in-time learned whatever their employer required, or whatever particular tools someone else on their team chose for a project.
As an old, it took me a while to recognize/realize it, but I understand them now. Depending on their career path, someone will encounter the simplest aspects of HTML, CSS and vanilla JavaScript after they learn the complex, framework-specific aspects of each. It feels (to them) like more esoteric, advanced, or tertiary knowledge.
Tying it back to to the quote "that’s a lot more work for us", that's not necessarily an intentionally false claim. It probably does feel like a lot more work to perform a task using unfamiliar tools, even if they are less-complex tools.
There is! You just have to time travel all the way back to 2009 when webOS was launched by Palm. Time travel is the easy part, you then also need to somehow prevent Palms demise and webOS fading into obscurity as a smartphone OS.
If 2009 is too far back you can try your luck in 2012 with Firefox OS.
Joking aside, people and companies have given it a go. But a combination of bad timing and various other events never made that reality happen in our timeline.
Embrace Extend Extinguish is real, and the people going along with it deserve to be replaced by a LLM that lies and spits out garbage code just like they do but faster.
I created a couple libraries to abstract the SQL and HTMX/web/OAuth bits; my apps are now very similar and easy to copy features between.
I can't imagine this kind of traffic without acting as a CDN, advertising broker, pornographer, or part of a massive ecommerce site. I have to wonder, what are you doing that generates 10TB of traffic per month?
Your Go server can have endpoints that render XML instead of HTML and basically get the same server-driven experience of your HTMX site. Fully skips the need for the app review process since you're not updating the actual client app code to make UI changes.
Very cool!
> But yes, lately I’ve been building mobile apps. ... What can I do?
I am currently building HTMXNative.
Together with Objective-Smalltalk, which has linguistic support for REST built-in.
The idea is that you create your model in a natural way and then thinly wrap it to deliver wherever.
Because there isn't a 30% walled garden you can create with that.
Pages has a 20k-100k limit on static files, but if they just guide you to R2 to offload it, which is still Cloudflare.
Did you mean the CDN? In which case, I'm not seeing that in the terms. [0] Though, I would have expected they'd have a similar thing. R2 resources don't generally count towards your cache limits.
[0] https://www.cloudflare.com/service-specific-terms-applicatio...
Better would be to use plain HTTP in addition to TLS, rather than instead of TLS. TLS does have benefits, but if it is optional then it can also be used on computers without TLS (as well as potentially other situations where you do not want TLS or where it is not useful).
If you're using a decade old phone to sign up for a utility, you've got bigger problems in your life and no self-respecting person should be adding to them.
All completions were real people. It's a government website.
If the button doesn't work, the average user is going to say "this most be broken" and then use a competitor (or contact your support). That's why it's really important to error-proof one's design (eg https://en.wikipedia.org/wiki/Poka-yoke).
So instead of the button failing because you didn't check a box, pop up with a message telling them "Please click $box before continuing". Or if you want to be fancy, feed them whatever form you're giving them piecemeal, so that they can't continue until they finish this small part (e.g., have them input a name, then the next page only has a spot for an address, then the next page only has a spot for card information, then the next only has a spot to select shipping). Simple bite sized chunks anyone (well, anyone you would ethically want to sell to) can understand.
Aren't insane.
When did the industry put the onus on the user to understand how the computer works? What happened to the old days of Xerox PARC's HCI studies putting the user first? The computer is in service of the user, not the other way around!
If I need to build a mental turing machine to understand your application, it is a bad application. It is rather the engineer's job to build a mental model of the user and their needs, and if you can't do that you should not call yourself a software engineer.
A few decades ago, IT jobs were for the most part done only by people who were in it for the kick they got out of working with computers. They already hacked at their dad's computer in their early teens (or sometimes even younger), and just could just never let go. It was for people who loved it because it was a niche.
But today, IT is no longer that. It's the backbone of much of our society. And so the field no longer attracts just the die hard fans, the nerds. It attracts ordinary "career people", who just need to have a job to feed the family. Who turn the machine off after 8 hours. Who don't go on coding all through the evening on their hobby project. Who don't try out new tech just for the heck of it.
I think it's hard to understand if you belong to the first group, the nerds, that anyone working in the field isn't like you. Because they all used to be! But those days are gone. We live in the times of enshitification for a reason. If you have the hacker spirit, you don't enshitify because you simply can't. You know what is the right way to do it. Sometimes that's a React app but sometimes it's just an HTML page.
You're not just in it for the money. You care. Not necessarily for the end user, although that would be nice. You care for the tech. And when - like in this article - both come together, sweet things can happen.
I'm not a web developer. I built a few websites in high school, but these days I write safety-critical real-time code for robots.
A few years ago I was back in grad school and I took a class with undergrad senior CS students. We had to write a fairly simple web service, and I was blown away by how complicated they were making it. Based on the requirements we easily could have written 90% of it in plain HTML, but everyone else insisted it should be 100% react. Part of that is honors students wanting to do everything the most complex way possible to impress teacher, and part of it is them simply not knowing that other options exist.
You realize that someone who was 18 when the Mac was first released would be 60 now?
Personal anecdote: Recently they were updating everyone to "smart meters" on the gas lines. They needed me to be home so they could enter my apartment and bleed the gas out of the line by turning on the stove prior to replacing the meter. I played phone tag with them for 6 months, setting up countless appointments, and nobody ever showed up, the meter remains un-upgraded. At the same time, I have received weekly phone calls and monthly physical letters stating that if I don't upgrade the meter, my gas will be shut off. I just moved, so the new tenant will have to deal with it now.
The public sector, simple, no frills, accessible, no flashy graphics, websites were a massive eye-opener.
They just worked. They had a job. They did it. I wasn't going to buy more from them because of it, and they didn't care. It was great.
I've heard that recently they've dismantled the centralised team that wrote all the rules, enforced it, and started moving to decentralised hosting, but so far the whole still seems to hold to together really well. I think, I hope, they have embedded the expectation that the local council, the tax office, your visa status, etc, should just be utilitarian in nature, and work for everyone.
I worry how long it will last...
Nice work!
May I ask what tech is used for mobile apps? I am guessing not a full mobile app but it uses webview.
In Defence of the Single Page Application - https://news.ycombinator.com/item?id=31275178 - May 2022 (32 comments)
You could argue that the constraints of using HTML-first (as they call it) helped them stay away from the bad patterns they were using before.
But you’re right: The user change came from fixing the design, not the technology used.
This is a lot like those bad resume bullet points where someone tries to claim an increase in business was due to their code change. “Increased visitor count 100% by rewriting website to be HTML-first”. Then when you ask them about that point they concede that the entire site was redesigned to fix some design problems or add a feature and that’s what drove the visitor increase.
facebook was super popular in 2014s because they were just starting the transition from mostly being about people to mostly being algorithmic rage bait, and they tapped a new market of fox news/conservative talk radio listeners
The article is clearly aimed at non crappy developers or developers who want to do better for their users.
And it provides an anecdotal experience where an HTML first option developed by a good developer was far superior to what a JS necessary option would have been, given the user base of this application.
2. The design constraints had always existed, the previous app just failed to meet them.
But I 100% see where the author's coming from, considering the massive fragmentation of react codebases/patterns and decision paralysis of React development in general. I really doubt most React apps, even the more accessible ones, are testing their multi-page form wizards with JS completely turned off.
HTML-first does seem highly underutilized in the commercial web, and I learnt a lot from reading this (as a solidJS/react dev).
* Have working back/forward buttons * Have working progress indicator as provided by the browser * Show errors to the user - even if they are ugly * Be accessible to keyboard navigation
With SPAs these are all things the developer has to get right.
So often when using a SPA I'll click a button, you get a spinner and then nothing will happen. Is it still in progress? Don't know. Eventually I'll open developer console and trace the network requests to find the JSON HTTP request that returned "ERR_BAD_EMAIL" and fix what I've entered. With a normal form submission at least the user will see the error message and can press back and then fix it.
An "old school" Ruby on Rails/Symfony/Django app, with templates, usual get/post forms etc, frames you and pushes you in using the standards and relying on browser default behaviors.
In JS-heavy apps, it's as easy to code normal `button` elements as it is to code clickable `div` elements. But with the divs you just forget to handle keyboard nav, proper element roles, etc. It's easy to create fake links, not relying on `a` tags, using an internal JS router that doesn't expose URLs, doesn't handle middle click mouse, for no particular reasons.
In less JS-heavy contexts, the easiest way to do is to use proper HTML so you are less inclined to mess up.
Even on codebases that use a decent framework like Next.js that handles those for you on paper, it's often we see people not very aware of the benefits of using proper semantics and standard behaviors, and you easily end up with web apps with poor UX in the end.
And their mobile device should be the cheapest Android phone from a monthly cell provider you've never heard of. This is what the real world is for a lot of people, and a huge number of developers simply don't know or care.
download the whole app and run it in browser. you can even run it off line!
I generally prefer solidJS nowadays, but the react ecosystem has enabled lots of amazing user experiences (and developer experiences too if you don't fall into the trap of overcomplexity).
Keep it simple and light. HTML+CSS first, JS to expand functionality. Don't re-invent the wheel.
And don't dare to contradict me, the fact that MIT-bred leetcode ninjas paid half a million per year can't produce a simple (mostly static) website on that stack it's only because of management that wants to ship the next product. /s
You're being generous with what I would consider negligence.
You've only got yourself to blame, there.
These are the people writing React monstrosities for government benefit websites, and testing them on fast iPhones and fast 4G, without realizing that every page load for actual users will take 30 seconds on their old $200 Android on 3G, and users won’t complete the form.
It’s a culture of not giving a shit, that’s the deeper issue.
It's like how a lot of people these days reach for an electric drill/driver for even the most simple projects like tightening a screw. It never occurs to them to use a screwdriver, or even a butter knife.
This is a direct effect of being a low barrier industry to enter. Most of the ppl among us are mostly here because of a good paycheck. And it SUCKS!
Working on a "simple html page" that is actually 5 different independent "subpages" (routes, views, templates) in the backend is awful. The UX was improved, but the DX was sacrificed.
I recommend having a single view function for each page/SPA and do sub-routing within that function to handle page fragments. In other words, use a GET/path/Header parameter that indicates which fragment is currently needed, defaulting to the full document as normal. Just make sure you are considering request logging and client-side caching in your solution.
This makes it very easy to add/remove async content from the page, since you are just editing the one view function/template and you can easily reason about the entire page as one logical unit.
It also means you don't need to duplicate security logic or other middlewares for the page, since it can be implemented once at the start of your multi-faceted view function.
Fun thing, TFA describes a kind of multi-page wizard style form that I haven't seen a lot anymore in the last decade or so. But when I did see it, it's always some dogshit enterprise system. Some Oracle product for expensing expenses last time.
The problem with those things always seems to be that they are slow in the middle of doing your task. Every button is seconds of waiting. Doubly annoying if you have to go back a step or two. The badly coded SPAs seem to be slow at the start. It takes a while to load, but once it's loaded its performance is usually okay.
I can't imagine trying to use links/lynx or a browser with less market share than FF that isn't based on chromium.
There were always certain UX requirements that required JS, and that meant the company wasn't interested in testing to make sure it worked without JS. None of their customers were going to use it that way.
Angular, React, etc helped force it further, but they didn't cause it.
Sadly, the internet as a whole seems to disagree. Even the most useful resource on the web one could use over plain HTTP, Wikipedia, only allows connections over HTTPS. I guess it kind of made sense as part of the campaign to push the internet as a whole over to HTTPS, but anyone who's connecting to any website over normal HTTP these days is doing so because they literally can't use HTTPS.
I've seen static sites with these same problems, 404 was invented decades before React...
You know, it's time to stop this trope.
People who are 60 today were born in 1966, they probably entered the workforce in the mid 80's. They probably are not even retired yet. They know how to use computers, they own a smartphone (or if they don't, it's probably for economic reasons unrelated to their age).
As a founder and product manager, this kind of thinking is unhelpful as we design the future. In many ways it's actually ageist to imply that old people are unable to utilize everyday technology.
I was building public service websites (BBC News website) back in the early 2000's where accessibility was a real and important consideration. Technology progresses, and the bar for accessibility has moved up.
My father is about to turn 80 - he checks his heart with his Apple watch, video calls his grandson from his iPad, and asks ChatGPT questions from his iPhone and MacBook Pro. Maybe he's more unusual for 80yo's but it's time to stop this lazy trope that old people are technically illiterate.
(also, shit, I'm only 15 years away from being 60 myself :/ )
I think this is a bit outdated. I'll be 60 in a month, and have been practicing and writing about machine learning, for money, for a straight 10 years now; and I was a young man (and a full stack developer) during the digital revolution.
If anything, GenX had to work harder to get into these brittle emerging technologies and paradigms. There's no-one of my age group, at least that I know of, who is remotely as tech-illiterate as your comment depicts.
Truth is that it took so long for smartphones to dumb down everyone's tech acumen that those of my generation had already learned to do it the hard way.
> A venerable web application pattern that has had a small modern renaissance thanks to Remix, form submissions and redirects took a while to explain to my colleagues, on account of everyone being used to heavily client-side web applications.
(Although it's not really a joke, it's pretty amazing how many professional web developers these days don't know how to use forms without JavaScript.)
Either it works right away without any further questions, or they'll not do it.
Sadly, also if they can't do it on their phone, they will not do it. It's actually very hard to get people motivated to do anything that has to do with sitting down at an actual computer anymore. Which is a bit hard if you're in a very technical political advocacy group, kinda makes me the guy to do everything remotely complex... XD
Just after the turn of the century, that was when there was a big shift in the industry to move all user interface design work to artists, and away from original user interface specialists. The whole profession of user interface designer (one who understood "form follows function") ceased to exist in the early 2000s, as all work was assigned to graphic designers (who only understand aesthetics).
This movement can be seen clearly in the evolution of widget toolkits for desktop applications, which peaked in usability in the late-90s/early-2000s, and have been losing usability while getting prettier with every iteration since.
This is even true for things as seemingly non-technological as getting to your flight once you arrive at the airport. People who are used to dealing with a service desk might just show up with their printed ticket without even having looked at it, take it to the counter, and expect instructions on what to do next without having read or considered all the fields present on the ticket.
It's not just about understanding the technology, but sometimes about understanding the business, policies, whatever. When a human agent or customer service worker is handling that stuff for you (typical in the pre-computer age), you barely have to think about that stuff and even if you're told, it can be "in one ear, out the other". Automation very often means pushing a requirement of more understanding onto customers/users.
The pendulum is overdue for swinging back the other way, but I don’t know who or what has both the capability and will to give it the push needed to send it on its way back.
The frontend was in React because the company that got the contract initially used React for everything. The frontend was a 5MB SPA, but it could've been (mostly static) HTML files with some interactivity for forms like TFA. Everyone working on the project agreed React didn't make sense, but we couldn't do anything about it because someone from the government IT department would have to admit they made a mistake. There was no budget for rewrites in the contract. The few times a developer attempted to remove any "React monstrosity" they got in trouble.
Sometimes developers care, but the people in charge don't, and in government environments every change must go through them first.
The behaviours of developers as well being beholden to their managers rather than the craft; meaning not saying No we will not move forward without proper unit tests, or pushing back when business demands quick corner cutting solutions.
Anyway, decades of bitterness. I wish we had associations to uphold some level of accountability on developers as much as protect developers. I think things would be a lot more expensive and slow if we did that though.
Fundamentally I agree with your take, not just on dev side but just the web/dev/produce' a culture of not giving a shit.
I like how HTMX does SPAs. It straddles the divide nicely between simple and capable.
“HTML only? Nobody is doing it!”
Absolutely agree! Just because I understand how they got there doesn't mean I think it's a good state of affairs ;)
My post was already quite long, and I didn't want to append a treatise on what one should do when encountering those engineers. It depends on many details. Avoid hiring them, if that's a power you have. If you are stuck working with them, depending on your authority, encourage them to learn or force them to learn. If you're coming in to clean up after them... well, hopefully your comp is worth the annoyance.
We are all simultaneously in the position of encountering "the world as it is", understanding it, and doing what we can to improve it.
Running `npm install` on Android isn't so easy.
(Caveat: The new Android Terminal that only works on a handful of models.)
"Satire isn’t dead.
Satire won.
This is what it looks like from inside, looking out. "
Astro itself works just fine with React, and it can still be HTML-only.
But you can also render React on the server yourself using renderToString, if you don't want a framework.
Agree that most people didn't, but I was always an advocate.
If you are concerned about accidental login or API keys without TLS, then you can consider supporting mutual TLS, which improves security (and flexibility) in other ways as well. (You do not necessarily, have to require mutual TLS, in case someone prefers to use a username/password login, or 2FA or something else like that instead.) (In the case of login forms, you can have the links to the login forms to always use HTTPS, in order to avoid the problem.)
Maybe this isn't applicable to all software devs. If you make web apps, users actually see your UI, they click an icon or type in a URL and hit enter with the intent of using the thing you made. With firmware, that's not how it works.
When you hit the "mute" button on your laptop keyboard, it should just do it. The audio should turn off and the little LED should light up. If that fails, even once, the mirage is broken. The user is forced to think about the fallibility of firmware, which is a word they might not even know, and still struggle to conceptualize if they do. I think it also has a lasting effect on the way someone thinks about the pruduct: Is this going to work today? Why did that happen? Was that a virus? So on.
OTA firmware updates have the same problem. Most users don't know what the hell firmware is. All they know is their computer is showing a loading screen they've never seen before. It's unfamiliar and weird.
Like I said, I don't know if this mindset translates perfectly to other fields, but the priorities that fall out of my philosophy certainly apply. Reliability over everything, and get it right the first time.
My experience was the reverse. I learned HTML and CSS first, then Rails in college to serve templated pages. I understood the client/server boundary fine as a concept, what I couldn't see was where it actually sat in a web context. I sort of knew JavaScript ran in the browser, but then I'd see ERB templates stamping values directly into script tags, so the server was writing the JavaScript that ran on the client, and my mental model fell apart. Where does my code actually execute? Why does this variable exist here but not there? Why does the page have data the network tab never fetched? Nobody ever sat me down and explained the request/response lifecycle as its own thing. I had to assemble it from fragments over years. This was around 2017 for context.
How you learn something shapes how you keep learning. If your mental model is misaligned, everything downstream is friction. The thing that finally made it click for me was reading the actual HTTP RFCs, which is apparently a weird thing to do, because HTTP itself is absent from nearly every guide and curriculum. Tutorials teach you the framework, maybe the language, and just assume the protocol underneath. These days I make newbies read the MDN docs like a book and skim the HTTP wiki page, learn the history of the protocol. It's short! It's not even a book! That gives you a firm foundation. But if your foundation starts at React, drilling down is like digging past bedrock. People don't know where to start, and Googling only shows them wrong answers because they don't yet know how to ask the question.
(I still very much support fast, simple HTML websites. The good ones are a fantastic user experience)
It doesn't work if you disable JavaScript...but it wasn't always this way!
They had a mobile version of their online banking service at https://m.chase.com that was EXTREMELY FAST and did 85% of what you need to do in an online banking portal (check balances, transfer funds). They scrapped it when they moved to their current bloated monstrosity of the portal that they have today.
It was a big reason why I moved to a credit union (who outsources their online banking services to Alkami, which maintains a very tight portal and supports 2FA AND passkeys!).
Jun 10, 2026
This is a story of how building HTML-first doubled a company’s users literally overnight.
My client was a utility company, and they had a big problem. To apply for their services, customers could either use an old ASP form on the website, or follow a manual process. The manual process was more expensive for the company, of course. Adding a lot of pressure, this was a regulated monopoly, and if their customer satisfaction dropped below 96% (if I remember correctly) it could result in millions of pounds in fines.
There were two previous failed (and very expensive) attempts to solve the problem. In the most recent, contractors in another country had built a React app. The React app was online for 3 days before being pulled because of customer complaints. I took one look at it and told my boss “we can’t take ownership of this.” It was a mess of loading spinners and global javascript states. It was not accessible. Image upload was a vital part of the form, and it attempted to store images (along with all other form data) in localstorage which has a 5mb limit!
I took a very bold decision and built a new version of the site using Astro. It was HTML-first. Javascript existed, in web components, but only to progressively-enhance a website that worked perfectly fine without it.
My logic was thus:
I was very moved by this anecdote from Terence Eden:
A few years ago I was doing policy research in a housing benefits office in London. They are singularly unlovely places. The walls are brightened up with posters offering helpful services for people fleeing domestic violence. The security guards on the door are cautiously indifferent to anyone walking in. The air is filled with tense conversations between partners - drowned out by the noise of screaming kids.
In the middle, a young woman sits on a hard plastic chair. She is surrounded by canvas-bags containing her worldly possessions. She doesn’t look like she is in a great emotional place right now. Clutched in her hands is a games console - a PlayStation Portable. She stares at it intensely; blocking out the world with Candy Crush.
Or, at least, that’s what I thought.
Walking behind her, I glance at her console and recognise the screen she’s on. She’s connected to the complementary WiFi and is browsing the GOV.UK pages on Housing Benefit. She’s not slicing fruit; she’s arming herself with knowledge.
The PSP’s web browser is - charitably - pathetic. It is slow, frequently runs out of memory, and can only open 3 tabs at a time.
But the GOV.UK pages are written in simple HTML. They are designed to be lightweight and will work even on rubbish browsers. They have to. This is for everyone.
Some requirements I derived:
The basic setup ended up being that each step in the form wizard was its own page. When the user clicked next, the form would submit. If the data was judged to be valid by the API, the browser would be redirected to the next step.
A venerable web application pattern that has had a small modern renaissance thanks to Remix, form submissions and redirects took a while to explain to my colleagues, on account of everyone being used to heavily client-side web applications. I have nothing against heavily client-side applications, in their place. But this is just a big form - it’s not showing real-time data. Our user could be standing in the middle of a field on a new-build housing estate, holding a decade-old commodity android phone they bought in Tesco. Shipping them 20MB of javascript before we even render a form would be a ridiculous thing to do.
Next, I tackled one of my biggest bugbears, form validation (and form and form error rendering). I have seen teams waste person-months of effort wrangling React validation libraries. If you are a React person, you might be scoffing at this - skill issue, I guess - but it is the reality for many teams. I would like to humbly suggest that you too may be spending more time than you realise, and a lot more time than is necessary, interacting with and maintaining poor imitations of the validation system that ships with every browser.
So I built an HTML web component. These are simple custom elements that wrap around existing HTML and bring it to life. No shadow DOM, no (or little) rendering HTML in javascript. Mine wrapped around any HTML form, picked up the HTML validation, and made it look modern. It would prevent those HTML validation popup tooltips, and instead place the error in the aria-describedby element associated with the field (today, aria-errormessage is advised instead). It would clear validation while you typed, if you reached a valid state, and assess it again on blur and submit.
Exactly the user experience a form needs, delivered in under 1KB. If it failed, the form would fall back to built-in browser validation. If that failed, the backend API would handle validation. We reported validation issues to the user as early as possible given their browser, and always fell back to an acceptable experience if it failed.
I have since written a new version of this web component from scratch, aimed for general use. It’s called validation-enhancer. I have been in this industry for over 20 years, and it is the best form validation library I have ever used. I am very proud of it.
The code is so simple to work with:
<validation-enhancer>
<form>
<label for="my-email">Email</label>
<input type="email" name="my-email" aria-errormessage="my-email-error" required />
<div id="my-email-error"></div>
<button type="submit">Submit</button>
</form>
</validation-enhancer>
The results? When we launched, the number of people completing the form doubled. The analytics people didn’t even know where these users were coming from. Of course, your javascript-based analytics package doesn’t see the users you are bouncing because of javascript failures. It was a flood! We also saw my “keep a backend session, never lose user data” approach pay off. In one case, someone completed a form a month after starting it.
There was a sad coda; as is the way of contract work, I moved on. I explained what I had built to my replacement, that it always worked even without javascript. He was appalled and said, “but that’s a lot more work for us.”
It is not acceptable to bounce users on old browsers, users with bad network connections, users using assistive technologies. Certainly not from a monopoly public service. A lot of hype and noise is pressing us to extend the cowboy, wild-west phase of the software industry’s expansion. We should set that aside, and take ourselves seriously as a mature industry. Build a web application that works on a playstation portable on a 3G connection - if you do, it will work for all your users, and it will still work 30 years from now.
I wouldn’t sweat the broken fridge either though, there’s so many other electrical appliances in the house to use.
"I click the <next> button on this form, nothing happens. Given that I have an internalized notion of forms as a multistep flow, maybe it couldn't advance because something is missing on the current step? Maybe it will give me those messages below or above the form? Maybe some read message somewhere? I'll search for those and try again"
vs
"I click the <next> button on this form, nothing happens. Not sure what would happen next. Maybe the thing will tell me? I can't see no dialogs, no messages, no error screen. Nothing changed. Maybe if I press it again? Nothing? Hum, maybe is disconnected from the network? It's the wifi again? Maybe if I power cycle the wifi router it will reconnect? I click next again now I get a clear error message: no internet connection. I suppose my internet is broken again. Will call my tech-savvy friend."
> Adults at this level are able to understand simple problems and develop and implement solutions to solve them. Problems contain a limited number of elements and little to no irrelevant information. Solutions at this level are simple and consist of a limited number of steps. Problems are embedded in a context that includes one or two sources of information and presents a single, explicitly defined goal.
This test is administered on a tablet, so I think scores can be interpreted as a sort of combo of computer use and problem solving.
A full 40% of adults from 55-64 are at that level or lower. Wikipedia thinks that a novel online form would be a Level 2 task, provided it involves navigating across more than 1 page. Based on that framework and assuming your dad can use the sort function in his email, he represents a top 20th percentile adult for the 55-64 age group. It's probably even higher considering his age as the trend is towards older groups having a rougher time with the survey.
I also think it's ageist to assume that older people can't use a computer. But assessments like this indicate that a full quarter of the US regardless of age would have trouble with some of the basic tasks we associate with computer use. So designers should consider their intended audience when deciding what's simple or not simple enough.
[0]: https://nces.ed.gov/surveys/piaac/2023/national_results.asp
Instead of "old person" he put a number on it. (Cue the people who need to cut me down because I used a male pronoun for an unknown poster)
I have been asked by someone in late 40s why uploading a video takes a lot longer than uploading a photo.
They are not dumb people. They just do not know.
The onus is on the engineers to design for them.
I'd be curious to see the stats on how often Next.js users lean into the server component model that makes the frontend fast. My anecdotal experience is that it's an afterthought for many. By comparison, Astro (as mentioned by the author) makes you think about this stuff upfront via opt-in rather than opt-out. It's a wonderful framework.
P.S. your solution seems to have disabled the custom font instead of fixing it
"Why did the bank change the layout? I want the old one back!" - Don't like it? Change bank then. That's what I did.
I get that changing to another bank is a big unknown, but it's probably still worth it to show your displeasure. Plus her bank are morons when it comes to several other things.
my mum, a boomer now in her 70s, would have no bloody clue what you're talking about. she used to work helping out a guy who was doing punchcard programming back when she was young. she ain't dumb. if i broke it down into normal human english words, she'd probably get a sort of idea (or at least nod along to humour me).
i've lost count of the number of conversations i've had with my dad, late 70s boomer, where he complains that they've changed the UI. "It's all different and i don't understand, why did they have to change it? I don't know where anything is now." he's been moaning about things like this for over a decade now (so since his late 60s).
there are definitely technically not-very-literate 60 year olds and the general point about older folks, whether that's >60 or >70, is very real:
older people exist who don't have a clue about SPAs/PWAs, and chances are they're either asking their offspring for help (my mum does this), trying to phone someone instead (my mum does this) or just walking away from it (my mum does this).
This is my philosophy too working in infrastructure. It’s my job to care way too much so downstream users don’t have to.
> Is it slow though? Like in practice?
The multi-page wizards? The ones I've seen were. Enterprise crap systems.
This is an absurd statement. Just because something is a proverb, doesn't mean it's automatically true for all cases.
Someone at chase isn't checking their work on firefox.
I mean, we learn that a enroll is normally a flow. Flows have steps. So if you came to the end of the flow and the finish button is gray, you think.
Hum… I'm used to flows. This is a multistep flow. Flows normally need me to fulfill some small checks and won't let me proceed between steps if something is missing. But some won't. Maybe this is one of those? Some flows have warnings in the end, some have next to the thing missing. I don't see any warn in the last screen, so I'll go back every step and check field by field for errors. That'll probably do.
This is the model you have in your mind, of how a website or an app works.
People that came to computers, apps and websites later in life didn't learned the puzzles.
My mother, born in 1934, had no problem using computers. She didn't internalize how they work, but she learned the workflows she needed. How to launch applications and so on.
The situation described in that comment is just a broken app, it has nothing to do with the age or the understanding of the user.
I recently had to intervene during the latest office holy war to explain that you don't need JS for file uploads.
It was eye opening.
Looking at the code, I found it was using UI elements for data storage and other such nonsense. A colleague and I had to tell the manager that the entire thing had to be rewritten. I'm not sure he actually went pale, but that's how I remember it.
FWIW, maintaining at least a moderate degree of empathy even in systemically frustrating situations is good for the empathizer and thus in one’s interest
Crazy enough, I also hold doctors and surgeons to higher standards than web developers.
My main bank changed their UX not too long ago, and I liked the old one better, but the banks I've signed up for since are even worse. I signed up with them for other reasons though, so I put up with them because it's worth the pain. It does make my main bank look better though --- mobile style on desktop is annoying, but at least I can easily find everything I need... And it's not really their fault there are seven different options on the transfers page (including my favorite: same day transfer vs next day transfers... at one point same day transfers had a fee but they don't anymore so from a user perspective, it's the same thing but you can have it slower if you want...)
Also, signing up for a new bank these days is an exercise in KYC frustration. And then you can't actually transfer your money and use it, because banks responded to the dumbass check fraud that was being promoted on social media by limiting new accounts.
React is too heavy weight for a lot of things. But it's ridiculous to call it disrespectful.
> A poor workman blames his tools
which is towards the opposite meaning
A professional woodcarver armed with only a metal spoon will still make a nicer woodcarving than I can given a full wood shop. Similarly, if you only give me notepad.exe, I can still make a pretty nice website.
Does using the right tools make our lives easier? For sure. Using mildly-wrong tools (react, in this case) isn't going to hold us back very much though.
I agree. Better to deal with the devil you know rather than potentially one you don't.
Thankfully, I switched to a bank with a UI that was known good going by all the chatter I'd heard, but that's not really something you can guarantee to know. And even if you do know, if the rate is drastically worse at that bank than any of the others', then that's kind of moot.
Absolutely. I am in full-time work, and expect to be for another decade. I have worked my entire career in IT, doing tech support, training, systems design and implementation, tech journalism, and tech writing (i.e. documentation).
I will be 60 in less than 18 months.
> Word processors and spreadsheets having been ubiquitous for office workers from at least the early 90s.
You did say "at least", but still... longer than that.
I started work in 1988 and they were already ubiquitous in my world. Richer companies had the fairly newfangled IBM compatibles, which were still big and expensive. The cheap Amstrad PCs were just starting to appear.
Older hands had multiuser boxes with SCO Xenix or DR Concurrent CP/M or Concurrent DOS and a bunch of dumb terminals. My company had switched to these from Alpha Micro systems running AMOS -- and again, dumb terminals. One of my clients had a DEC PDP-11.
The real old hands had 8-bit kit: some CP/M, and a few BBC Micros.
The first big migrations I saw were from standalone (or multiuser) PCs to LANs, and from pre-PC systems to PCs and Macs.
60-year-olds who worked blue-collar for a significant part of their life, this is not so obviously true for.
Also probably not true for 60-year-olds who worked in other non-office jobs, like acting or sports.
There have been a variety of well-paid jobs that didn't use computers that a 60-year-old might have done over their life, meaning that this can't even be broken up along class/income lines.
if it sounded "clean" on all 3, without the bass muffling everything, and the highs not hurting the eardrums, we called it "good" and released.