[b]ack

I Strongly Dislike JavaScript

2026-06

JavaScript is slow. Not slow in the sense of a few milliseconds, but slow in the sense that the browser must download it, parse it, compile it, and execute it before the page finishes loading. Every kilobyte of script delays time-to-interactive. Every DOM mutation after first paint is a potential layout shift. Every fetch in a useEffect is a round-trip that didn’t need to happen.

The modern reflex is to reach for a framework at the first sign of interactivity: React for a toggle, Vue for a dropdown, a 40kB runtime to handle a click event. Most of the time this is completely unnecessary and the developer just hasn’t thought about it long enough.

what this site does without javascript

Theme application. Colors are set before the first paint via an inline <script> in the base layout, a few lines that read from localStorage and write CSS variables to :root. It runs synchronously during HTML parsing, before any stylesheet is applied. It uses no framework, produces no flash of wrong colors, and runs in about 200 bytes.

The SVG icon explorer. The gallery on the SVGs post lets you select any icon and see its source code. Zero JavaScript. The whole interaction, highlighting the selected icon and showing the matching code panel, is driven by hidden <input type="radio"> elements and the CSS :has() selector. Click a label, a radio checks, :has(#sv-work-1:checked) targets the matching panel and shows it. CSS has gotten expressive enough that what used to need a toggle class and an event listener now needs nothing.

what actually needed it

The canvas. Generative art requires <canvas> and the 2D drawing API. There’s no CSS equivalent for procedurally placed sine ribbons. This is the one case where JavaScript is irreplaceable and the tradeoff is obviously worth it.

The clock. Real-time updates need setInterval. CSS can’t read the system clock.

The cover strip scroll sync. The shelf page scrolls the book and film cover strips in proportion to the list below them. This needs a scroll event listener. It’s about fifteen lines and it’s genuinely useful.

The quote panel. Cycling through a shuffled pool of quotes with a fade transition needs JavaScript to swap content and manage state. This could theoretically be done with radio inputs too, but the pool is large enough and the fade specific enough that scripting it was cleaner.

the rule

If there’s a CSS solution, use it. If the browser already handles it (focus management, scroll, form state), let it. JavaScript is for the things that have no other option: animation that depends on runtime state, periodic updates, and data that has to change after the page loads.

The question is not “can I do this in JavaScript?” The question really is “do I have to?”