> its API was a reflection of the domain. As a developer, I want to query for a node (CSS selector, xpath, etc.) to affect change and traverse to other nodes
That's what I miss about it.
Genuinely asking, I have no clue what's being alluded to without being clearly mentioned in this thread.
Array.from adds friction. The need to wrap querySelector in null checks adds friction. The fact that they are not composable in any way, shape, or form, with any DOM methods (and that DOM methods are not composable) adds friction.
jQuery was the fore-runner of fluid interface design. Nothing in the DOM before, then, or since ever thought about it. Even the new APIs are all the same 90s Java-style method calls with awkward conversions and workarounds to do anything useful.
That's why sites like "You don't need jQuery" read like bad parody: https://youmightnotneedjquery.com
E.g. what happens when it's not just one element?
$(el).addClass(className);
// vs.
el.classList.add(className);
Or: why doesn't NodeList expose an array-like object, but provides an extremely anaemic interface that you always need to convert to array? [1] $(selector).filter(filterFn);
// vs.
[...document.querySelectorAll(selector)].filter(filterFn);
There's a reason most people avoid DOM APIs like the plague.---
[1] This is the entirety of methods exposed on NodeList https://developer.mozilla.org/en-US/docs/Web/API/NodeList
Instance properties
- length
Instance methods
- entries() // returns an iterator
- forEach()
- item()
- keys()
- values()
ES2025 added map, filter, flatMap, reduce, forEach, and several other methods to all iterators (including NodeList directly, I believe, but definitely its entries(), keys(), values(), if not) [1]. It'll be a year or two at current pace before that is "widely accepted baseline" in browsers, but it's great progress on these sorts of complaints.
[1] https://2ality.com/2025/06/ecmascript-2025.html#iterator-hel...
I listed all public methods and properties of NodeList. It does have a forEach, so there's not much need for `for of`
As for iterator methods, I completely forgot about that :) Yeah, you can/will be able to use them on .entries()
But to me, these are minor inconveniences and habits. A thin wrapper can get you there easily if you care enough. I personally dislike this array/element confusion that jQuery adds.
But that's more and more friction. A wrapper here, a wrapper there, and if here, a try/catch there. At one point you are reinventing significant chunks of jQuery
- a plugin system
- its custom selector parser (because it had it before querySelector and is not totally compatible with it)
- its abstraction to iron out browser differences (old IE vs standard, notably) that's not relevant anymore
- its own custom (DOM) event management
- its implementation of methods that are now standard (ajax & trim for instance)
I recognize that the DOM API could be better, and comes with friction. Back then, ironing out the browser differences and its selector feature were killer features of jQuery. Today, I do not think the quirks of the DOM API warrant importing a library like jQuery.
¹ but indeed, very lightweight compared to modern frameworks like Angular, React and Vue, with all the ecosystem which comes with each of them (react-router, redux, etc).