HTML Is Enough

Fun fact: you can build a website with only HTML and CSS.
And no, this isn't some "JavaScript is dead" nonsense.
HTML is actually pretty damn capable. Not in the abstract — concretely, with zero JavaScript.
Form validation, no JS
That's real validation. Wrong email format, empty field, age under 18 — the browser blocks submission and shows a native error message. No library, no onChange handler, no state.
Want custom styling on invalid fields instead of the browser's default popup? Try the inputs above — empty or wrong-format fields get a red border, valid ones turn green. All of it CSS.
A modal, no JS
<dialog> gives you a real modal — top layer, backdrop, focus trap, Esc to close — built into the element. Opening it takes zero JavaScript: the popovertarget attribute on the button does it, and clicking outside, pressing Esc, or hitting Cancel closes it. Try it.
A dropdown menu, no JS
Options▾
- Edit
- Duplicate
- Delete
<details>/<summary> is a fully functional disclosure widget — the one above is live. Click to expand, click to collapse. The CSS inlines the styling so it doesn't look like a <details> element at all, and most users will never know.
Now the part everyone skips: where this actually stops being enough
I'm not going to pretend HTML/CSS covers everything, because it doesn't, and pretending otherwise is exactly the kind of vague-take nonsense that makes this genre of post useless. Concretely, you need JavaScript (and maybe a framework) when:
- Cross-field validation — "confirm password must match password," "end date must be after start date."
:invalidandrequiredcan't see across fields. - Async validation — checking if a username is taken while the user types. That's a network call, full stop.
- Client-side state that outlives a page load — a shopping cart, a multi-step wizard, anything that needs to persist without hitting the server every time.
- Real-time UI updates — live search filtering a list as you type, a chat interface, anything where the DOM needs to react to data changing without a full page reload.
That's the actual line. Below it, native HTML. Above it, JavaScript — and only once you're stacking multiple things from that list across a large enough app does a framework start paying for itself over vanilla JS.
Which is why this still bugs me:
Someone needs a contact form with an email field and a submit button, and the stack becomes React, a router, a form library, a validation library, a UI library, state management, 400 npm packages, and a node_modules folder the size of a black hole.
For a form that native required and type="email" already solve.
Come on.
I'm not saying frameworks are bad. React earns its place the moment you're doing real client-side state, real-time updates, or a UI complex enough that manually wiring up DOM updates becomes its own maintenance burden. That's a real threshold, not a vibe.
I almost always reach for HTML first, then CSS, then JavaScript. Only when the problem actually hits one of the things on that list above do I reach for Svelte or Vue.
The browser already gives us a lot.