Ask HN: What happened to vanilla HTML/CSS/JS development?
I'm not a web developer, but I dabble in it because I find it interesting. I went through some courses like The Odin Project and others to learn the basics of HTML/CSS/JS, and I thought it made a lot of sense: HTML structures the page, CSS handles the style, and JS handles the functionality.
However, after working for software companies for a few years, it seems like almost nobody uses these technologies in the way they're presented on websites like w3schools to make web applications. Instead, they use component-based frameworks like React. To me, these frameworks seem way more complicated than HTML/CSS/JS, and I don't understand what problem they're trying to solve. What makes the trade-off of all that extra complexity and abstraction worth it? Aren't HTML/CSS/JS perfectly fine and time-tested tools for web development on their own?
415 comments
[ 2.9 ms ] story [ 408 ms ] threadFolks open-sourced their libraries, others contributed, and we eventually wound up with frameworks.
The larger a code base gets, the more complex it can be, and frameworks help abstract ideas (like design systems), rather than having to repeat component code, css, each time it is needed. Also, if more developers are being added to the code base, the scaling of a project can get quite large. We have over 50 developers working at my company coding on the website.
Security is another. When updating a list of items (for example) from a fetch, vanilla js will require direct modification of the html, whereas a framework like React will handle that, with best security practices applied, as the code has been written and production tested.
I'm not going to deep dive on language features, can be quite subjective, for example how great Typescript is (compiler errors > runtime errors), or how SASS fills in a lot of missing features for CSS, etc.
I think some websites could be done in vanilla JS/HTML/CSS, but as the site scales, I feel at some point a developer would build their own framework to make things easier and streamlined. It's what developers do.
I don't use React. I learned a little bit of Vue. I'm definitely not an expert, but I think there are (at least) two problems that they solve: consistency and reusability.
Consistency: I think the hope is that if you're a React programmer and you see a brand new site written in React, you'll understand it, whereas if it used vanilla JS, it might be written in any number of ways.
Reusability: if you start writing your own reusable functions in vanilla, you'll eventually build your own React -- it's the build vs. buy decision.
Eventually, the original guideline of HTML for structure, CSS for styling, and JavaScript for interactivity started to not really make sense anymore for many websites, because as pages became more interactive, the lines became blurred. If you look at a site like GMail, where does the page structure end and interactivity begin?
With large parts of a page being interactive, it becomes difficult to manage all the state involved, especially if it’s a “live” page that updates in real time and may have several people viewing it.
Frameworks were introduced as a way to manage state and allow websites to re-render efficiently without hard page refreshes.
But most sites aren't GMail. Frameworks and typescript should still be the exception, and the rule should still be independent, modular libraries like JQuery.
People always say this but it's so hollow. Most sites aren't Gmail, but we're not building most sites. We're building applications that work in similar fashion to Gmail, thus need similar stuff like all these frameworks provide.
"Oh but everyone's using React to build their blogs instead of writing new posts for them and that's overkill"
Let me stop you before we get to this point. People use their personal blogs as a way to test new concepts they want to learn, so of course it's gonna be over engineered to hell.
I pushed back hard on introducing React when the site already had jQuery. Another developer said they could do what was needed with React.
The marketing site started shipping both jQuery and React.
I hate the JavaScript/React ecosystem so damn much for its complexity.
I hope you find a new job. That's like saying you hate bananas because someone asked for a pie and you said you'd make an apple pie and they said they'd make a banana pie and they decided to choose the banana pie instead of your apple pie.
I don't like PHP/Laravel ecosystem because I recommended we use vanilla PHP and my co-worker recommended we use Laravel and my manager decided to use Laravel.
I don't like Python/Django ecosystem because I recommended we use vanilla Python and my co-worker recommended we use Django and my manager decided to use Django.
Swap it with literally any framework in any language vs using vanilla-<lang here>. It all sounds just as ridiculous.
Yes, but you failed to note it's just your interpretation, not what the GP said himself. And you continued by assuming your interpretation is correct, suggesting that the GP should get fired because of it.
In reality, your interpretation is most likely not what the GP meant, and you clinging to your uncharitable interpretation in the context of GP comment was what I called "uncalled for". Please review the HN guidelines, this situation is addressed there explicitly (argue against the strongest interpretation of what others say, not the weakest; argue against what was said, not a person who said it). It's worth revisiting the guidelines from time to time, even if you're a long-time user.
In this case, the more sensible interpretation would be something like this: the ecosystem where you have to include two completely different frameworks to get things done is overly complex, and the complexity is what the GP hates. It's perfectly valid position, too.
Uh, where did I say GP should be fired for it? I said "I hope you find a new job" because he sounds unhappy at his current place.
I know marketing sites that were just static and I know marketing sites that had highly interactive examples and needed to have React on the page.
And JS shouldn't be exceptionally bad but here we are, and people use TypeScript as alternative to stay sane.
I agree that modern web development comes with far too much complexity on average, but people started adopting those frameworks for a reason. The web is kept backwards compatible with obsolete standards which have been created in a different time for different purposes, and at some point it becomes easier to build abstractions over that. For example TailwindCSS adds another "compilation" step and configuration file but in return makes styling much more tolerable than standard CSS. Is it necessary? No, but when you build a large website all those little things add up.
The DOM though is definitely complex and built of accretion over time. The Web resists refactoring because we can’t break websites from the 90s.
I agree; it's a plague all dynamically-typed languages face. I've yet to meet one that doesn't hit me with some kind of powerful pain-in-the-ass corner cases as a trade-off for the power of its terseness.
I fell in and out of love with Python over the course of a decade or so. Initially very excited about doing so much with so little code; fell out of love when I used it in an industry setting and realized 100% unit test coverage was mandatory because the lack of variable declaration means every line of code is a potential runtime error in waiting due to a simple name typo.
There's just no way to know that `if foo:` doesn't reference a foo that's supposed to be on the global scope.
(Contrast JavaScript, where `use strict` was added to force explicit reference to non-local scope).
You can explicitly mark a nonlocal or global as well.
Now if your project needs to be impervious to malicious actors, additional safeguards will be needed. But I’ve never encountered this situation in a long career.
Unless I'm mistaken (and please correct me if I am), no Python linter can address the fact that
`y = myVoriable + 3`
... is valid Python code because there's no way to know a-priori that `myVoriable` isn't a valid global variable, even though human inspection makes it obvious that it's a typo on `myVariable`. For that reason, there's a practical limit on how much static error checking Python allows as per the design of the language.
Has this been changed in the past decade? If so, I should give this language another chance.
The error message is slightly obtuse, says something like "variable only used once." But is clear after inspection the first time.
Ouch! As a google mail theft victim, "right in the heart" :(
> efficiently without hard page refreshes.
And completely destroying the "Back-forward-refresh" functionality.
It's a history of one decision after another, made hastily, often in anger, and it's how we got ... here.
My emphasis added.
There are still absolutely tons of sites for which the classical model works fine, and indeed works better than React at al, because pages load faster and behave more normally.
Some of those sites are now built with React et al anyway, for some bad reason (cargo culting, resumé-driven development, etc). But still, most are not, i suspect. Classical web development is still a very useful skill.
However, i suspect that although a majority of web sites don't involve React et al, a majority of web development jobs do - because the fraction of sites that are complex enough to need React et al also need a lot more developers!
(a fact i think is fun: a majority of stars are in binary or multiple star systems, even though such systems are a minority of star systems)
https://github.com/altilunium/
Not acceptable if each person working for 2 years builds his own abstractions that new hires have to learn - but you make it easier by using framework and hiring devs for that framework.
Not acceptable if you would have 20 of such teams and you would have to have UI/UX standardized.
Unfortunately, because the web is serious business, all of that complexity became the standard for the entire ecosystem.
Just using HTML/CSS/JS is considered either regressive or niche. It's called "vanilla js" which only shows how utterly locked in to the enterprise paradigm javascript has become, when what should be the default needs its own genre identifier to differentiate it from "the norm."
There certainly is a decent subset of web development work where HTML/CSS/JS is still reasonable and viable, but it tends to be less complex, and low-code/no-code tools like Wix or Retool are quickly taking over that space.
https://github.com/mdn/web-components-examples/blob/main/pop...
As a backend dev who can do a bit of traditional style frontend, I fail to see the need for all this complexity. Most apps are running same database queries and displaying it on a webpage.
https://www.primefaces.org/showcase/index.xhtml
Also the library you linked can hardly be considered vanilla HTML/CSS/JS
It surely is more vanilla, as originally it was designed to work with JavaScript disabled, if so desired.
Also vanilla HTML/JS does not mean html that works if JS is disabled. It means you are literally writing out the document that is delivered to the user without transformations or a huge runtime library included.
This JSF is not vanilla HTML: <p:commandButton value="Update event2" update="@obs(event2)" icon="pi pi-check"/>
Still the point holds, component frameworks exist for 20 years, it isn't an invention of cool kids JS SPAs, and they work without JS if needed.
PHP was always a anything goes, Rails never impressed me having used AOLServer and being part of a team that created a similar architecture with TCL (Safelayer mention above, the founder of that startup created Outsystems), express is basically a servlet engine in terms of features.
I was not recommending Wix, and obviously there are plenty of downsides to using something like it. The fact remains that it has captured a lot of the market that would have used vanilla HTML/CSS in the past. That is what the OP was asking about.
It's similar for CSS with the added twist that it's a fair amount of work to get something non-hideous. Much better to start with something reasonably good looking and tweak from there.
This is not unheard of in languages that have an HTTP server and router built into the standard library (Go is the most prominent example here, but I've seen many node.js web services written w/o 3P frameworks). You could argue that the stdlib functionality is a framework, just not one that you need to install, but the same could be said of vanilla HTML/CSS/JS.
In a regular straightforward program you apply a change and read it back only when it is needed. Even if that change is cached/computed/transformed/etc, there is only need to observe it when your program execution comes to that part.
In a ui program after doing a change you have to somehow update all the relevant elements/controls that are currently visible on a screen, i.e. replicate the whole state of a program into a graphical context at once (regardless if html or not). This process has associated costs and is pretty error-prone if not addressed systemically. All these frameworks spin around some idea of optimization of it. Since it can't be done without tradeoffs, they invent new ways of thinking about a problem, offloading parts of it via methodological contracts to a developer, who pays their half of the price. Different developers have different opinions on how high the price should be and which trade-offs they should take.
Is it worth it? Sometimes yes, sometimes not really. In my opinion, ideas behind some frameworks are useful by themselves, but in general all this tends to become more religious rather than technical. E.g. if you weigh what "cost" is or how error-prone the straightforward approach is, you may find that for some cases it doesn't really matter.
I wrote a complete warehouse management system. I wouldn't be able to accomplish this in a relatively short time frame without help of frameworks and libraries. Instead of using vanilla SQL queries I used LINQ. For UI, I used bootstrap, because it made it easy to handle desktop/mobile. For async calls I used old jquery because it worked well enough with .NET and was well documented. Additionally .NET allowed to scaffold models and identity.
I can write a site in JS/HTML/CSS, however, why? I would rather do things quickly with proven frameworks. Size of websites is less of an issues these days. There may be use cases for going pure vanilla but often not the case from a business perspective.
Don't get me wrong, it's perfectly possible to create spaghetti in React, but it just makes large codebases so much more manageable, and the tooling and ecosystem around it is massive.
Typescript with React and a bundler, linter etc. is just an amazing developer experience, compared to the mess those of us who did front end development in the past remember.
---
We are building SyncHTML.io to counter that.
Try at https://sy.ht (press up/down arrows)
See how we set ourselves apart https://efn.kr/b/sync#new-playground
---
Web standards are unbeatable when used right.
They are not used right most of the time.
---
See 2 custom elements done right™: (The /?s at the end is significant!)
1. zero-md: https://md.sy.ht/?s (just press up/down arrow keys)
2. WebPDF.pro: https://pdf.sy.ht (view); https://pdf.sy.ht/?s (edit)
(The WebPDF.pro elements are served from an unoptimized server. Takes a few seconds to load.)
When I go to https://sy.ht, I see a clock animation on the right and a blank editor on the left. I tried arrow keys and nothing happened.
Got ERR_CONNECTION_RESET from https://efn.kr/b/sync#new-playground
What are you sharing? Is this a codepen-like thing?
This is what I am sharing: https://sy.ht/yt (YouTube video showing what this is about.)
I once inherited a project where the front end was split between like +20 different react projects across that many git repos which we really had to twist the arm of the original developer to get access to. That's definitely an example of doing it wrong.
Same goes for HTML/CSS/JS, in fact, CSS and JS are the answer to the limitation of HTML and static page serving which was the vanilla www. As for your question, I don’t see HTML/CSS/JS going anywhere, they are the building blocks of web development and are written as such.
3 mins... or were you looking for a server-side component as well?
JS frameworks allow front-end developers to get around this limitation by rebuilding parts of the platform as a JavaScript application. For example, if you want to customize how navigation works on your page, you can either use the few, limited hooks offered by the browser (e.g., registering window.onunload callbacks), or you can make navigation an application concern by writing your site as a single-page app. There are plenty of things you just can't do with a framework-less multipage site (like animate transitions between pages) that are possible once you make navigation an application rather than platform concern.
I can understand why many enterprise teams choose to use front-end frameworks like React even when it would arguably be faster and easier to just use vanilla JS, as there's a risk someone may need to add functionality that is not supported by the native web platform. For personal projects, though, I use vanilla JS and HTML.
And you lost me.
Is it possible to write reusable JS/CSS/HTML? Yes but the overhead is very frustrating and you will quickly find yourself building a custom framework to manage everything. Best to start with a framework from the start if you plan on having rich interactions. The speed at which I can move in VueJS is nothing short of amazing and the amount of reuse I get is extremely high, all without me having to manually manage a bunch of files/includes. With 1 TS import I can get all the HTML/CSS/JS for a component and safely use it in another component. At a minimum that would take 3 http calls in "vanillaJS" to fetch the html/css/js that I would need to maintain and update myself. SFC's are a game changer. Sure the browser might eventually support what I need but by that point I have no doubt that VueJS (or similar) will have lept further ahead.
It's the same reason I jumped on the 6to5/babel train early, it let me write my code in ES6 but still deploy to older browsers without waiting on everyone to upgrade.
I’ve tried to go back to plain html/css/JS before and it’s a huge pain. I’m constantly thinking “ugh, this would be 2-3 lines of code in Vue but instead I have to manage all this stuff myself and it’s going to take 10’s of lines if not more. I’m not a fan of reinventing the wheel, also my skill set can be used everywhere if I write all my stuff in Vue instead of needing to context switch between smaller and larger projects (and again, small projects almost always grow so why not set them up for success?).
We call out to libraries when doing things that are better handled via a library.
Guess what, when you use a bespoke solution for common tasks, you end up with something that blows past every other competitor's benchmarks, without even trying.
e.g. take a look at Benchpress, our templating engine: https://github.com/benchpressjs/benchpressjs/
At this point you're building a crappy version of a module and package manager, but all by yourself, nobody else is using your stuff, and you can't use their stuff either because it's not in your bespoke format.
All of the examples and concepts here are just inter-project related, but this applies within a project all the same.
The reason react was invented was to enable real time update of items on the page -- to update when someone liked your item, or send you a notification update instantly instead of polling the server.
It was the idea of pushing code to the webpage. So they made a component in javascript that updates in realtime -- the state or prop determining the content or how many likes the post had. However this ended up requiring a huge Redis instance which is also very expensive, so now they need to sell more ads. In order to figure this out they realize emojis on the like button allow people to choose a sentiment of their reaction to the content. Their ML uses the sentiment to group and sandwich ads between content the ML knows or thinks you will react favorably.
So for example, a comedy central ad will be shown after a meme or story that is similar or something you reacted Haha to because the advertiser's desired reaction is a Haha as well.
Thus the name React. Plus it makes that div/element/part of the page defined as a "component" in js that will update or "react" in realtime -- anytime they push an update to the server everyone viewing that page sees it change in realtime.
Essentially a combination of a push notification or pubsub and ajax request.
Honestly, when jsx goes out of style like it should because its idiotic, and gross, and a violation of those separations of concerns, it could just be an html page where you write a js function to add a realtime update to an id or class...
Svelte uses that style of approach to the DOM.
If you don't have a realtime data store like Redis or any type of realtime data streaming going on, React or any other component based framework is a waste of time.
The ability to update the page without reloading or building as a single page app is not SEO friendly unless you use SSR which you already would have created in your normal seo friendly html files.
also name your files consistently and clearly.
unless you need to change the page in realtime without reloading, react and these other component frameworks have no use case.
If you want a clean css3 framework to help build a web front end that works neatly in html5 check out Bulma.
Bulma.io
You are exactly right, the js developer scene is like a herd and people wanted to work at facebook or look smart so they learned it.
It's useful for making single page applications, however all framework interactivity can be written in normal js, so if you take your time you'll have much cleaner, unbloated code, yielding pages that run better and faster...
Certainly, not building a website. MAYBE building certain kinds of apps, like a game or a paint app (see: most action is truly on the client-side).
---
I found a simple stack that is super-productive & efficient: https://tailwindcss.com + https://htmx.org.
This is, IMHO, the best way to do "normal" websites, even the ones some are tempted to get nuts with stuff like React (eCommerce, blogs, chat app,...).
The best is that it actually embrace the web as-is and not requiere anything to degrade correctly.
They do, of course, add their own wrinkles, but at the time of adoption ostensibly the juice is worth the squeeze--at least for whatever real-world challenge a given team (or the broader dev culture) is facing at the time.
---
I'll still use pure HTML/CSS/JS for client projects, depending on the context. Usually for static sites or interactive UI/UX prototypes, both in freelance and day-job (agency, bigcorp) contexts. So far, folks are very happy with the outcomes, but I do vet the fit first. :)
In other contexts like enterprise/SaaS apps, Shopify builds, etc. I won't insist on no-JS or avoiding React/SPAs, as much as I'd secretly like to, but I will advocate for self-hosting and minimizing 3P JS dependencies where we're not necessarily gaining a huge increase in capability in exchange for dev convenience, etc.
It's a balance.