Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
I loved jQuery, and still do (2019) (withblue.ink)
191 points by notoriousarun on June 29, 2021 | hide | past | favorite | 182 comments


I still use jQuery even for new projects. Yes, these days it's possible to do everything jQuery does using native JS, but I find the native version to be much more verbose and its naming conventions to be far less clear.

For example, natively getting a list of children is `el.children` but natively getting the parent is `el.parentNode`, not `el.parent`. Meanwhile, natively getting a list of classes is `el.classList`, but when I'm getting children I also get a list, so why not `el.childList` instead of `el.children`? Natively cloning a node is `el.cloneNode(true)`, so now I have to remember what `true` is for and whether I want it or not (surprise: the default changed between JS versions, so the "optional" argument must always be included for compatibility!). Probably the most commonly used line in web JS in jQuery is the terse `$('selector')` but natively is the mouthful of `document.querySelectorAll('selector')`.

So while jQuery isn't strictly necessary, it's certainly a nice syntactic sugar, and IMHO a more sane and consistently-designed API than native. It's a great choice for developers who want avoid big frameworks like Vue and get as close to plain HTML/JS as possible, but still want a pleasant JS development experience.


> For example, natively getting a list of children is `el.children` but natively getting the parent is `el.parentNode`, not `el.parent`.

Actually, .children is the child elements; .childNodes is all the children (including comments and text as well as elements).

> Meanwhile, natively getting a list of classes is `el.classList`, but when I'm getting children I also get a list, so why not `el.childList` instead of `el.children`?

I’m not sure why they want with .classList instead of .classes, but I expect .className is a part of the history. If redesigning it from scratch and still retaining the functionality of .children, I’d rename it .childElements. Certainly not .childList.

And of course, the reasons for most of this stuff is the history. Some of the web’s APIs have aged well; others haven’t.


jQuery is nice for small widgets (if you don't mind loading another library), but as soon as you start to make truly reactive content, it falls on its face. A reactive framework like Vue essentially makes your javascript variables control what is rendered implicitly based on their value, instead of explicitly calling a function.

Since the ViewModel binds the variables to the controls, hundreds of lines of jQuery required to update controls literally vanishes. It blew my mind once I understood what reactivity meant in real life. I rewrote a fairly large site in Vue and the JS LOC shrank by nearly two orders of magnitude (of course, a lot of that was due to the previous webdevs problems).

Now that I'm used to Vue, I view jQuery more like a skin disease, some kind of rash that makes everything ugly and swollen.


You can just assign document.QuerySelector and document.QuerySelectorAll to $ and $$ yourself.


You can, and some JS consoles provide this for convenience if those vars are unused, but jQuery really shines with method chaining. That’s what I miss the most from it. You could manipulate the DOM in incredible ways in “one line” of code.


FYI chaining and a handful of the most common operations can be implemented in just a few lines of code: https://gist.github.com/paulirish/12fb951a8b893a454b32

(Although I reach for the "cash" library instead of this or jQuery when I need something jQuery like)


Depends what you want to do, but I've kind of come around because I feel like if what I want to do is so complicated that I can't easily do it in vanilla JS, it's also complicated enough that I don't necessarily want to do it by manual DOM manipulation. Changes the calculation if you have to support older browsers and such though.


I've used jQuery in the past, but switched to native js/ts.

I found that while jQuery offers some nice synthetic sugar, it's mostly geared towards web frontend and actual logic continue to have to reside in native. I'd rather just know one thing (but I'm a backend programmer that only does js/ts for fun, so there's that).


Mostly geared toward frontend? It’s been a while since I used JQuery but I thought it is specifically a frontend library.


Maybe they mean UI?


> but natively is the mouthful of `document.querySelectorAll('selector')`

I'm curious as to whether there's a proper use case for querySelectorAll. I always use the getElementsByClassName, getElementById, and getElementsByTagName based on what I want. I find the more general querySelectorAll to be too likely to produce a bug when someone uses a CSS class name that equals a tag or ID. You can make it work, but I find it's too easy to re-use a word in different context, especially if it's different people doing the coding vs CSS.


Selecting descendants or sibling elements? Selecting based on tag and class? Selecting elements with a given attribute present or matching a particular value? Selecting elements with classes starting or ending with a given string? Selecting elements without children? Selecting elements that aren't any of the above.


The question should be the other way around: Why is there `getElementsByClassName` when you can do `querySelectorAll('.myClass')`? Why have `getElementById` when we have `querySelectorAll('#myId')`? Why have `getElementsByTagName` when we have `querySelectorAll('tagName')`?


Apart from the historical reasons both `getElementsByClassName` and especially `getElementById` are optimised - the latter being a simple lookup - which I'm not sure `querySelectorAll` is able to take advantage of.


You’d pay the cost of parsing every time, but otherwise I’d expect SelectorAll to directly depend on getElementBy.. as relevant


I use it all the time for bookmarklets and userscripts when I want to customize a page that I can't modify directly. Vendor site showing too many out of stock items? querySelectorAll('div.out-of-stock') and wipe them all out. Filter options not good enough? querySelectorAll('div.price').forEach( /* delete products between x and y prices */ ).


class, id, and tag name are only a small subset of the things you can get with a css query, and you can't combine them with anything when you use the dedicated querySelector methods.

document.querySelectorAll("[data-my-attr=something]")

document.querySelectorAll(".foo > [data-my-attr=something]")

etc.


getElementsByClassName and getElementsByTagName return live HTMLCollection objects that update when the DOM changes (or rather get re-computed when you access their contents following a DOM change). Depending on what you do with them, you may end up with worse performance compared to the NodeLists returned by querySelectorAll.


It’s slower but, assuming you have control over page content, I’d think the answer is probably pseudo selectors or sibling selectors. The more complex stuff really.

Of course if that’s a need the page needs work but, not everything is “fixable” in time limited business cases.


Every time anything about jQuery is posted, someone will inevitably post the "You might not need jQuery" site. [0]

I look at that site and laugh. Is this supposed to be making the case ~against~ jQuery? Maybe the audience for that site are seasoned developers for whom the vanilla JS syntax is easily understood. Everybody else is going to look at those code snippets and think jQ is the way to go.

For people that have struggled through HTML and CSS, there is perhaps nothing more deflating than to realize that even basic UI interactivity requires JS. But with jQuery the code snippets needed are short and understandable. Vanilla JS in comparison looks like an entirely different language.

[0] http://youmightnotneedjquery.com/


> Is this supposed to be making the case ~against~ jQuery?

It's supposed to be making a case against jQuery if you're pulling in the whole library just to do this one thing.

I've always read the site as "here's how to do it in native JS, yes it's uglier, but if you only need this, you can skip pulling in another dependency."


We use React, Angular and Vue for websites where 99% of the functionality could be done without monstrosities like CSS-in-JS.

Over-engineering websites has been around forever. That's partially why jQuery is modular, letting you pick what you need.This covers the 'use jquery for just this one thing' crowd. And if they're lazy, well, they can hang their heads in shame because they have added an entire 83 KB to the page's initial load time. /s

(unless the browser has a CDN cache stored, in which case it wouldn't impact load time at all)


note that browsers' cache has recently been changed so that it's isolated for each origin - if you visit a.com which loads jQuery, it doesn't speed up loading jQuery on b.com at all https://developer.mozilla.org/en-US/docs/Web/Privacy/State_P...


I can see where you're coming from, but just wanted to add a counterpoint.

I recently removed jQuery from a website, and the YMNNJQ website was one of the bits of info that gave me the nudge to do that. The website in question only used jQuery in a handful of places, it was one of the few third party libraries being used (so the % size savings was significant), and I'm fairly fluent with JS... The website simply hadn't gone through a major update in the past 5 or 6 years, and the browser landscape has shifted enough in that time that the pros/cons weigh differently now.

So I think there are scenarios where this info is sometimes useful in the "I might remove jQuery" sense, and not in the "wow, I'm definitely keeping jQuery!" sense.


In your example, switching from jQuery was just a matter of personal preference. There's nothing wrong with that.

My original comment left out some context: on HN, a lot of the hostility to jQuery is either cultural or gatekeeping oriented. Cultural opposition is of the 'not invented here' variety, e.g. 'Why use Dropbox when you could do this w/ rsync? Gatekeeping-related opposition is where it's implied that you shouldn't call yourself a dev if you use jQuery and not vanilla JS.

That is the kind of discussion that happens nearly every time a link to YMNNJQ is dropped.


That's not how I see jQuery hate.

jQuery promotes bad development patterns, AND brings a cost for end users. Developers will do themselves and futures devs a favor by not choosing to use it. Is it really gatekeeping to expect people to be aware of commonly used 10 year old features?

I assume developers who share YMNNJQ are just sick of inheriting messy projects built with jQuery. I know I am.


You've never inherited a terrible, unmaintainable React or Angular app? I have on multiple occasions, and in fact my team is dealing with one right now. I'd prefer a jQuery mess to an Angular/React mess any day of the week. With old-school jQuery apps, at least I can get them to build and can debug the control flow.


A couple of years ago I inherited a client's static site that was written in React before Next.js took off. It is a real accomplishment to make a static site as unnecessarily unmaintainable and convoluted as that one was.

Part of my screening process is making sure something like that doesn't fall in my lap again. Even static sites aren't safe these days.


> jQuery promotes bad development patterns

If you do web development as a job, it's your responsibility to stay up to date on what best practices are. With EC2015 being several years ago now, jQuery wouldn't be a learner's starting point today.

Those that developed bad habits during jQuery's heyday a decade ago may still be writing bad code. And it's someone else's job to clean that up. That's the circle of life, and it's hardly exclusive to jQuery users.


The article explains why jQuery doesn't promote bad development patterns. That is a consequence of bad development and a misunderstanding of what jQuery is.


> it's implied that you shouldn't call yourself a dev if you use jQuery and not vanilla JS.

I've never seen that. The closest I've come to seeing that is that comments that imply that using jQuery indicates lower levels of experience as a developer.

> Cultural opposition is of the 'not invented here' variety, e.g. 'Why use Dropbox when you could do this w/ rsync?

How is that "not invented here"? That seems more like a preference for open source software.

I looked at submission history and I don't really see either of those attitudes prevalent in a quick scan of the comments:

https://news.ycombinator.com/from?site=youmightnotneedjquery...


That site is generally aiming at providing exact replacements, and quite a few of its examples are not great for various reasons:

Some use a bad technique; e.g. “Empty” removes the first child repeatedly, which is O(n²) in many environments, rather than removing the last child repeatedly, which is O(n), or `el.innerHTML = ""` which is shorter and more efficient in general)

Some suffer because they’re supporting IE which no one should do any more (fite me); e.g. “JSON” is long because it’s using XMLHttpRequest, but the Fetch API would make it vastly shorter (`data = await (await fetch('/my/url')).json()`—as an aside, suffix await like Rust settled on is so much nicer: `data = fetch('/my/url').await.json().await`); and “Each” should use `document.querySelectorAll(selector).forEach((el, i) => …)`; and “Matches Selector” is just `el.matches('.my-class')` now.

Also some look bad because jQuery optimised an operation that isn’t terribly common or should generally not be done, such as most of the width/height things (most uses of measuring element dimensions in JS are unnecessary, bad or wrong; aim to use CSS most of the time), “Index” (needing to know that an element is the nth child element is decidedly esoteric), “Type” (if you use this, you’re almost certainly doing the wrong thing), and “Parse HTML” (picture me running away, screaming in horror; this method is practically a primed security grenade). And remember, jQuery having optimised these things means you’re paying to ship that stuff that you’re not using.

And finally some seem more complex because they’re matching some unnecessary jQuery complexity, e.g. in “Set Height” (and alike in “Set Width”), $(el).height(…) takes a string, a number, or a function that returns a string or a number—but you’d be wiser to write `el.style.height = string;` or `el.style.height = number + 'px';` rather than being unnecessarily flexible.

Most people that use jQuery use a tiny subset of its functionality. The site is about showing that most uses of jQuery could actually dispense with it at little cost, if they’re the sort that value performance and such and want to ship less unnecessary code.


> Fetch API would make it vastly shorter (`data = await (await fetch('/my/url')).json()`—as an aside, suffix await like Rust settled on is so much nicer: `data = fetch('/my/url').await.json().await`);

const data = await fetch('/my/url').then(r => r.json());


Hmm, forgot about that style. Where you only have prefix await, .then() can end up nicer (though I might split it into `const response = await fetch('/my/url'); const data = await response.json();` as yet another style), but if you can have suffix await, I reckon it’s much nicer. Goes well with fluent API styles.


> Hmm, forgot about that style. Where you only have prefix await, .then() can end up nicer

Mind that in this example the then is a little nicer only by chance that the continuation is quite trivial. If you'd need something more complex than the single function call it is annoying and if you do any later change to this code, you likely have to change this as well.

I typically go to the multiple lines, but wanted to show that there is a kind-off suffix await.

I am not used to suffix await, as i like to spot the places where i jump out of the coroutine easily. But maybe that would change if I'd use languages with suffix await more :)


Why is removing the first element repeatedly O(N^2) while removing the last one O(N)? Is it because its cheaper for the browser to remove things from the end of a NodeList rather than the front? (similar to how .pop() is cheaper than .shift() for larger arrays?)


On reflection, “many” wasn’t the best word to use; “some” would be better.

In the past, I believe that most or all browser implementations used array-like structures to do various things like this, and so removing the first element entailed shifting all the remaining elements, whereas popping from the end doesn’t require shifting any elements.

More recently, I believe that most or all browser implementations have shifted to linked-list-like structures, with bad patterns like this being a cited reason. (I don’t know the full story by any means, but I’m inclined to be disappointed by the switch, because for most access patterns arrays aren’t a problem at all, and use less memory, sometimes even being a smidgeon faster. But although I suspect they’d have better typical performance and certainly better memory size, they have vastly worse worst-case performance, being approximately O(n) instead of O(1) for some operations.)

Remember also when talking of NodeList like this that it’s a type for JavaScript to consume; what browsers use internally for representing their DOM is an implementation detail. A leaky one, certainly, in performance details like this and types like HTMLCollection and NodeList (especially live NodeLists), but an implementation detail nonetheless.


I agree that the vanilla JS snippets seem hilariously more complicated, but simplicity isn't everything.

In a corporate environment, if "I need to include jQuery as a dependency" involves asking another team how to set up custom deployment or whatever, and that is the difference of days between deploying a feature or not, then I'll definitely take the hit of 10 more SLoC vanilla JS.


If it's a corporate environment, the standards are different, understandably. But the hostility to jQuery is also primarily concentrated among corporate devs that seemingly cannot imagine that jQuery might be valuable for use cases other than their own.

Not every site out there is an database-driven SPA that needs QA review and a deployment pipeline each time an update is made. Lots of sites are just simple WordPress or even raw HTML pages that need a little bit of a facelift, with animations or transition. jQuery does the trick, and as a bonus, it's a much gateway drug to JS than the official ES6 documentation could ever be.


> little bit of a facelift

Proceeds to download 30kb (compressed) swiss army knife of a library when just a toothpick would do.

jQuery is about as much of a gateway to ES6 as pot is to heroin. Devs who still use jQuery have had 10+ years to learn `document/element.querySelectorAll()`. Longer for event listeners.


When you learnt something with better more easily readable syntax, it's kinda hard to make yourself use something worse to save 30kb, when that saving will be lost with a single image on the page you're loading...


Incidentally, there's a few lightweight jQuery-likes you can use if you just want a nicer syntax. Zepto and umbrella are popular.


Gosh. 30kb.

> Devs who still use jQuery have had 10+ years to learn

Or possibly we learned it in 9 years 11 months ago and still think jQuery was a more elegant solution.


The modern web is a soup of React, Vue and Angular packages with numerous dependencies. Couldn't they just use jQuery UI?


> Proceeds to download 30kb (compressed) swiss army knife of a library when just a toothpick would do.

I agree that 30kb can be big, especially since it's JS that needs to be executed, but on the other hand if the toothpick means you save a minute, you can use it to optimize an image and end up with a lighter and faster website.


I assume that's a pro-jquery site

I write random bits of scripts for internal use, I'm happy enough to drop the min.js in with my index.js, index.css and index.php files, especially if it means I can continue to use

  getJSON('/my/url', function(data) {
  
  });
Rather than

  var request = new XMLHttpRequest();
  request.open('GET', '/my/url', true);
  
  request.onload = function() {
  if (this.status >= 200 && this.status < 400) {
    // Success!
    var data = JSON.parse(this.response);
  } else {
    // We reached our target server, but it returned an error
  
  }
  };

  request.onerror = function() {
  // There was a connection error of some sort
  };

  request.send();
The 90KB of jquery is nothing compared with the amount of crap modern javascript frameworks put in on other sites.

I've just looked at one page I wrote which has a little jquery in it. The outputted data is 673kb, which takes nearly half a second to generate and load. The jquery file being static is down in 0.01s.

This isn't a problem


You could have used async/await and fetch along with a polyfill if you are concerned about compatibility with older browsers. ;-)


Maybe that's just me but I find the async/await stuff way harder to understand than a simple callback. Sure when you're going through callback hell you're glad to have promises and the syntaxic sugar, but for simple things the callback makes sense, especially since it's already how you use map and filter in JS.


I think that websites needs an update, too. It would be a bit more convincing if they didn't try to support IE, and explained why the native methods are better.

Starting with the Ajax exmaple isn't the best way to get people on board, either. Until the Fetch API was widely adopted, I also reached for a library if I had more than one very simple API call.


I love jQuery.

I can just drop in the library onto any existing webpage, and have almost complete control of the DOM with just a few lines of code. And the built in actions and animations are all so simple and perfect for the web. And the structure and naming is so good that I rarely need to look up any references anymore.

I get that browser support isn't as important as it used to be, but it is nice to know that you can just use an effect in jQuery and it will just work exactly as you expect it.


I don’t know how universally true this is, but I find that the easier it is to write the first time, the harder it is to maintain. For example, it’s really easy to write a python script but it’s harder to change. It’s harder to use types on a program the first time but it’s easier to change. I think that’s the core of the issue here with peoples negative feelings about jQuery. Sure it’s super easy to make the page do the thing but it’s a long term mess almost always - especially compared to something with more built in structure.


I'm not sure if that's true. I find jQuery much easier to maintain than vanilla or even some modern JS libraries.

> $("#button").on('click', function(){ > $(".modal").slideUp(); > });

Obviously a simple example, but this is really easy to understand - even for a non-programmer! The equivalent vanilla JS to do this is honestly pretty nasty in comparison.

The only problems I have seen when maintaining jQuery is when someone wants to drop in a bunch of custom functions they have designed in vanilla JS - or try to treat it as a replacement for a front-end framework.

But for it's intended purpose of adding interactivity into HTML content, I think it is still the king.


I finally learned some React a couple of months ago on the premise that as a designer, I needed a better understanding of the frameworks used by the developers I work with.

I know React enforces some better practices that my spaghetti-jQuery of yore never followed, and that I was getting a crash course in those practices at the same time, but I was nonetheless surprised at just how slow I felt working in it! It gave me a new appreciation of just how accessible jQuery is, and how intuitive its concepts are to someone without a background in software development, perhaps for better or worse.

Obviously this is a bit of an apples-to-oranges comparison, given the intended uses of the two frameworks, but for simple projects, it's hard to imagine a better balance of accessibility and flexibility than jQuery.


Sounds like you're working on jQuery-sized apps, not React-sized. The problem is that many don't know the difference, and everything is React-sized, even apps that have no business being anything but server-rendered.


Yep... I mean, part of that is a problem of "SPA everything" cargo cult; basic web page? SPA everything! Content management? SPA everything!

I manage my wife's electronic store that's based on WordPress, and I see absolutely no reason for ever changing it. I've written a bunch of custom scripts, all in PHP back-end and jquery front-end, and... It just works. And it's fast. And complexity is totally manageable.

But, I've also written a few SPAs for her business deployed as PWAs, and I can't even begin to think about how it would look like if I was using jquery for these tasks. React (or Vue or whatever) is an escape hatch from going insane in such situations.


The software I manage is a very complex asynchronous workflow engine sometimes spanning across hundreds of containers. It's our bread and butter.

Our marketing site is in Wordpress.


Note that you may have this opinion because you started with jQuery first, and you're already familiar with it. Some things are not at all intuitive for beginners in jQuery, either.


Django templates + Bootstrap + jQuery is all I've ever needed to make great, modern websites. Server-side rendering with some nice layouts and interactivity on the frontend. I've tried some of the SPA frameworks and I've always felt like my productivity tanked.


Do you develop REST API also....?

The fundamental issue is that it binds the server to the client, who must understand HTML structure. It also makes it more difficult to reuse the endpoints in different ways or for new applications.

Returning data and letting the client render it decreases coupling and increases flexibility/testability- you can run unit tests on the client for mock data, and run unit tests on the server to test the desire


I don't use Django but I use Ruby on Rails, and turning a server-side rendered page into an API is trivial. Rails requests automatically understand the format of a request and let you specify what do when a specific kind of format comes in: ie. when it's an html request, render this page, when it's a "js" request, render a jbuilder template. ezpz

whatever frontend framework you're using has really nothing to do with it at all.


Confirmed this is also trivial with Django, have done it to my crud, and even have a view that parses my url router for views and return an openapi definition with a swagger ui.


Do you use Django REST Framework with Web Swagger Console UI?


Nope, I have a view that parses my url router for views and generates an openapi schema, and a view that shows a swagger with it.


In General I agree, but using a SPA framework has one major benefit. It forces you to make an API for everything. So when a request comes in to make something more dynamic you have everything you need ready to go. Also, if you're building an app that some users need API access for, it's already there.

I daydream about making a framework that lets me use django templates as a SPA that does server side rendering on the first request, or when javascript is unavailable.


> using a SPA framework has one major benefit. It forces you to make an API for everything.

This is a drawback unless you truly need an API. YAGNI.

I've found a hybrid approach works well. Your site is mostly server side, but some individual pages have Vue and an API endpoint or two. If that mobile app or that third-party integration becomes a need, add endpoints for that particular use case.

I've gone the other route and prematurely optimized for the "what ifs" first, and it's painful when they don't happen and you're left holding all that complexity.


I had a big post but deleted it all. I can more concisely say this:

The people here saying they still use it have so far demonstrated what I always say. If you're using jQuery, it's time to go back and relearn javascript. Most people should REALLY research the querySelector and querySelectorAll DOM methods.

I've always felt that jQuery encourages you to let your skills stagnate and you don't learn what your code is actually doing. Learn what the current spec has to offer. You don't need another dep just to target dom nodes ffs.


I disagree, jQuery is still nice for some complicate dom manipulations and still simplify it a lot. Of course I'm not saying you can't do that without it, but saying if you use jQuery you doesn't know JS doesn't make sense.


For new projects I agree. Go jQuery-less.

But for existing projects that still work well and for which there is no reason or gain from updating the code and, for which, time and money would be spent for what is really a lateral move, I think it's fine to leave it as is.

And there are many projects like this where the JavaScript barely changes, jQuery is holding it in place and nicely and there's hardly any technical debt. There's no incentive to spend the money and time. Making a developer feel better is not really worth it in these situations unless they'd like to work for free.


I agree. No need to go into something that exists and do a big refactor to pull it out. I'm advocating for not adding it to things you start now.


> If you're using jQuery, it's time to go back and relearn javascript.

I've roughly as fluent in vanilla as I was in jQuery and I still think jQuery was a nicer, more elegant, more humane API to the DOM.


I've never really learned javascript in the first place - every time I try to learn I get caught up in a mix of versions of javascript(or ecmascript?), build systems, and just use "..." (coffeescript(lol), typescript, some node build system magic)

I build (barely) working websites with jquery and html and css though, having the "this is the one way jquery would do this and ignore all that other crap" value is high to me for that very reason - I work mostly on databases and having to learn the current spec every 2 years or whatever you web sickos are doing suuuuuuucks.


It´s been a while since I coded some front-end. What about issues with different browser implementations? jQuery used to handle those discrepancies.


> Most people should REALLY research the querySelector and querySelectorAll DOM methods.

Query selectors are like slow motion drowning in syrup. They are so astonishingly slow. They are also limited in what they can do.

Just learn the DOM. It can be learned in a single afternoon but for some reason people will fight you to death on this and then stake their careers on it like a heroic battle that nobody cares about.


Have fun when your page randomly gets visited by IE7 running behind some ancient corporate firewall.


i couldn't agree more!


If you're still using jQuery, maybe you don't enjoy web development, and you should do something you enjoy instead.


I created box2d jQuery https://github.com/franzenzenhofer/box2d-jquery (Demo Pages sadly down) a physics engine for the DOM.

I really learned to appreciate jquerys clean codebase at that time. Learned a lot about the DOM and how to misuse it.


That sounds interesting! Too bad it's down...


I'm not the biggest fan of jQuery because I have had to deal with massive tech debt created by other engineers over the years (and I'm not a frontend dev). However the Ajax API is a genuinely good tool.


The jQuery API is really good. It's still better than the DOM API, it's just that now, your framework might give you some of what it does, and the DOM API is almost good enough (and free). You're right about how it was historically misused, thought that has less to do with jQuery than a lack of good client-side frameworks, design patterns, and how rich frontend experiences used to start as just a few callbacks.


Do people still hate jQuery? I feel like the consensus is that that jQuery was a great tool for the time, but is not so critical today.

Yeah, we've all seen spaghetti code monstrosities that involve lots of jQuery, but it's just a library, it can't be blamed for people not knowing how to structure their code.


In 2012 or so we doubled down on jQuery UI, specifically the widget factory and a few dozen custom widgets extended from a custom parent widget. That application is STILL in production today, chugging along in both the private and public sectors.


jQuery is still my bread and butter for DOM manipulation and events. I've found it to be much more readable than vanilla JS.


Can you elaborate on what JQuery does for you that you can't do with modern JS features such as fetch and query selectors?


This page gives a pretty good overview of why jQuery is still relevant: http://youmightnotneedjquery.com/

Requests have gotten better with "fetch", but unfortunately, the "modern" DOM API is quite bad in some parts, making lots of stuff unnecessarily verbose. On top of that, it's really odd that the DOM API is not compatible with for-of loops, which could have been a selling point.


>it's really odd that the DOM API is not compatible with for-of loops, which could have been a selling point.

I'm not sure what you mean by that? querySelectorAll returns an iterable. Also, your link is outdated. It doesn't include the fetch API which has enjoyed wide support for quite a while now.


> I'm not sure what you mean by that? querySelectorAll returns an iterable.

Apparently my knowledge is outdated. Last time I tried to switch from jQuery to vanilla JS, the results of document.getElementsByTagName and others were not iterable with for-of.


jQuery has the most consistent return values I've ever seen in an API. It somehow always works. Contrasted to that the fact that a NodeList is not an Array gets me every time.


To use an example, I'd much rather do

$(".elements").css("color", "red")

versus

var selector = document.getElementsByClassName('elements');

selector.style.color = 'red';


The jQuery example is good, but the "vanilla" example is cleaner and simpler: the class name isn't decorated with a dot, the CSS property name is not quoted, $ might be hijacked or overloaded, it is not obvious (compared to a plain assignment) that css is a setter and what arguments it takes.


Sorry, that doesn't even work:

> document.getElementsByClassName('comment').style

> undefined

You'd need a for loop right there I believe.


You can do

const $ = document.querySelector;

$('.elements').style.color = 'red';

Which is only marginally more verbose.


No you can't. $('.elements') in jQuery is more equivalent to querySelectorAll('.elements').

You can however do:

document.querySelectorAll('a').forEach(a => a.style.color = 'red')


This is the only post that I see so far that touches on the real innovation and unique value of jQuery: operating on groups. Everybody can go ahead and tell me that using a forEach every time is trivial, or that I can just insert some transpiler step in my build pipeline to take advantage of X language's convenient syntax, but the bottom line is that people use jQuery because it continues to be easier. Thank you for your insight and great design sense John Resig! Still not bested after 15 years.


Though your alias definition needs a little extra, or the function loses its context and colling it will just result ":

  const $ = document.querySelector.bind(document);
or slightly less efficient, wrap in a function:

  const $ = function(x) { return document.querySelector(x) };
or if you want to be concise and don't need to support legacy IE:

  const $ = (x) => document.querySelector(x);
(and as pointed out already, you need querySelectorAll() and a loop for what jQuery does by default, though your example will work for a single element)


For me, the code is easily 10x more readable than vanilla JS. And much shorter, so I can hand code everything quicker without typos.


I just use vanilla JS now, but it took a while to get there.


That's 30KB over the network and 90KB of JS code in memory so that you don't need to learn about 5 standardized browser API methods that are the same in every browser going back to IE9 then. No doubt that gives you a better developer experience but I don't think your users are thanking you.


The internets users managed to live with this terrible 30k burden in the late 2000's when it was the only choice. I think probably in 2021 when 30kb is a rounding error on page sizes they can also probably manage it.


This feels like a false equivalence; how many of those 2000s users were browsing the web on mobile compared to today?


Does 30kb of js really matter on modern phones and modern mobile internet?


If "modern" means fast, then no. If "modern" means what people are using in 2021, then possibly.


This kind of thinking is why software continues to get slower and slower despite incredible advances in hardware.


Bingo. 30kb doesn't seem like much, but its easy to think it doesn't matter when viewing one dependency in isolation. But if you say "it's just x kb" to all dependencies, then you have a problem when they're all aggregated.

This is why I appreciate Svelte's take: with a compiler-heavy approach, you can have a great dev experience without saddling your users with extra dependencies.


Since many people seem to be religious today about which "packer" is the best and that using one in the first place is a necessity, the answer is apparently "yes".


> That's 30KB over the network and 90KB of JS code in memory

A fair point, but compared to the payload of most sites (let alone apps) these days that is chicken feed.

Just opened that page itself and DevTools tells me 5.2Mb was transferred including ~175KB of JS from twitter, 65Kb JS for the video player (which seems to have 46Kb worth of css associated with it!), ~1Mb worth of font resource, ...

> so that you don't need to learn about 5 standardized browser API methods

That and the way jQuery does method chaining, which a lot of people find far more convenient, but other features. jQuery does a lot more than querySelector/querySelectorAll/friends.

> No doubt that gives you a better developer experience*

<attenborough>And here we see a forum commenter in its natural habitat, hunting the point. It sidles up slowly, and pounces...</attenborough>

(with apologies for failing to resist being facetious and slightly dickish there)

>* but I don't think your users are thanking you.*

I don't think most users will notice. Those that do due to slow connections, metered connections, low-power/low-memory devices, etc, are going to baulk at much more before even noticing jQuery on this site.

On something like HN (23.8K transferred for this page before my comment was added) 30Kb might look chunky, but few sites are remotely close to being as lean as HN.


(with apologies for failing to resist being facetious and slightly dickish there)

No apology necessary. That was funny. Because it's true. :)


I'm not happy about it, but the reality is that 120kB is small potatoes in the modern web world. Would it be better without, sure? But there are bigger fish to fry. If jQuery helps the developer achieve their design and development goals, that will play out better for the end-user. It's not ideal, but it's realistic.


If jQuery helps the developer achieve their design and development goals, that will play out better for the end-user.

That's not the dilemma though. Developer can build solutions without jQuery. They'll be faster, smaller, and have fewer dependencies.

Plus, if you're only using jQuery for DOM and events then it probably isn't helping you. Those are two areas where writing vanilla JS is can often be easier than writing the jQuery code to do the same job.


jQuery versus vanilla DOM is slower, larger, and adds dependencies.

jQuery versus [framework of the month] is "faster, smaller, and [has] fewer dependencies". Simpler build, too, while still keeping you from having to worry about which browser supports what.

Depends on what the most likely alternative is, then.


There are plenty of modern frameworks that are smaller than jQuery (svelte, Preact, etc). In some apps they may also be faster. If you pick svelte there's the same number of dependencies.


I don’t follow. Is the implication here that users can identify an experience difference cause by a 30KB over-the-wire asset, or more, a 90KB in memory one? I know I certainly wouldn’t claim to have that ability myself even on low quality networks.


If you're a user on a spotty mobile connection in a rural location on a low-end device ... both.


In that case, most of the web is unusable nowadays, and jQuery is not your main problem. Maybe your argument is valid in less-developed countries where more people have spotty connections and more websites have adapted to that (but I wouldn't know, sorry).


30kb is pretty trivial. And even so, if you are using a CDN like you should the jQuery is likely already cached on the user device.


I recall an earlier discussion on here stating that using CDN nowadays doesn't have any gains, only drawbacks.


This is correct. It's called cache partioning. https://developers.google.com/web/updates/2020/10/http-cache...


Who cares when you're slurping down 40 megapixel PNGs for images that are sized with CSS to 100px x 100px?


Yes Jquery does makes things easier than vanilla JS

Best being

$("#id") replacing document.getElementById("id");

Makes code look cleaner


https://developer.mozilla.org/en-US/docs/Web/API/Document/qu...

Does the same as the $ query but native in every browser in IE9+ and gives you a native node. Also more performant than getElementBy<whatever> methods.


document.querySelector(selector) is more typing and more visual clutter on the editor screen.

jQuery is elegant, concise, and was designed by a genius. The "modern" methods are ugly, verbose, and were designed by a committee.


`const $ = document.querySelectorAll.bind(document);`


You can define your own `$` function. This way you can have the clean code without the entire jQuery library

    function $(arg) {
        if (arg.charAt(0) == "#") {
            // HTML spec does not support ids to start with numbers [0]
            // (you may not need this conditional on your website)
            return document.getElementById(arg.slice(1))
        }
        return document.querySelector(arg)
    }
Using this function you can select your comment with

    $('#27677234')
jQuery does add many extra features but if clean code is the only thing you are after there are other options.

[0] https://www.w3.org/TR/html4/types.html#type-id


The HN js actually does just this. The file isn't very long but has some great functions at the top

https://news.ycombinator.com/hn.js


True, but jQuery does a lot more than just id selection with $!

You could just extend the function to detect '.' vs '#', and do a class selection as well. And then add all of the selectors, subselectors, etc. (similar to, but far more powerful than css3's selectors.) and if you go far enough, you reinvented zepto (but still a long way from jQuery)

(actually, since $ is basically synonymous with jQuery, it'd probably be better to choose a different function name. too bad you can't define it as #(id).)


> True, but jQuery does a lot more than just id selection with $!

Yes. For a high degree of jquery-compatibility, you can use my library.

    const $ = document.querySelectorAll.bind(document);


This comment made me spit my drink out. People forget about bind, it's nice to replace the old closure patterns.


JQuery and backboneJS were all I needed up until very recently. Now it's modules all the way down, alien syntax and overengineering.


jQuery will always have a soft spot in my heart. I came from a design background and the naming conventions and "utility" functions for common events and selectors made it so simple to understand.


I agree with the author that jQuery was essential for the time. Abstracting away browser compatibility issues in the era of IE6 was a wonderful thing, for sure.

The problem is jQuery has no business being used today unless you have to maintain legacy code. Even then I would deprecate jQuery wherever possible. Using jQuery for a "quick and dirty" application today is just terrible and it sends the message to green devs that jQuery code slinging is a skill worth having.

If you like quick and dirty, just make sure you have a working Node.js environment and generate a simple project that supports Webpack or Parcel. You will get all the advantages of Babel and Polyfills (if you need them) with little to no effort.

jQuery has no value except for maintaining legacy code. jQuery was useful back in the day (and John Resig had the best solution), but I don't love it anymore. In fact, I have serious judgements of the devs that use it that should know better.

Edit: I should note that jQuery is bad because it has no state management and you cannot easily track side-effects. I would much rather see someone use something like Svelte and construct the functionality with modern best practices while keeping a very small footprint.


> If you like quick and dirty, just make sure you have a working Node.js environment and generate a simple project that supports Webpack or Parcel

There’s nothing quick or easy about these steps. Linking to a jQuery CDN and getting working code immediately is easy.


I respectfully disagree. If you take 15 min to understand the basics it becomes trivially easy and the productivity you gain going forward is massive.


I respectfully disagree if you have some other things to do in your free time than maintaining dependencies, trying to figure out why your project won't compile at all in 6 months of time while reporting 100 security issues, what will be the next change in webpack to will require to update both your config and some plugins, why does npm now cry for you to use a "--legacy-peer-deps" flags to nicely handle dependencies you didn't know you had while being happy you can't compile your frontend project on a small raspberry pi. It's not because you can use all those tools than you should


You are literally criticising Webpack for its best features. Identifying outdated libraries and potentially dangerous vulnerabilities is a huge plus for Webpack. Do you think just because you include a CDN lib in the global space vulnerabilities just magically go away?

You also don't need to include packages that are poorly engineered and maintained. For what you do decide to use, you are getting visibility into the warts that you may have blissfully ignored in the past.

The issues you are describing are not really problems anymore unless you let your app get woefully out of date. The web and browsers are a moving target, so it's critical that you minimize running legacy code wherever possible. Npm/Yarn and Webpack is a huge step in making that manageable. jQuery has been on autopilot for years because it has limited usefulness. We've collectively moved on except for a few holdouts.


You are literally criticizing jQuery for its best features. Not having outdated libraries and potentially dangerous vulnerabilities is a huge plus for jQuery. Do you think just because you use a build tool for modules from all over the npm-verse that vulnerabilities just magically go away?


jQuery has had its share of dangerous vulnerabilities. https://snyk.io/vuln/npm:jquery


agreed, but it's only one library, and might be the only one you need; really, it has an excellent track record considering that it's been around longer than npm itself.


I've been dealing with Webpacker for almost a year and it's been a nightmare every time I've tried to use it. And yes, I did sit down and try to figure out what the hell was going on.


Parcel is literally zero configuration, maybe that would have been a better solution for your usecase. You need to understand some Webpack basics for it to be functionally useful, but all the criticisms of Webpack could easily be levied against jQuery and some.


Vite is the way to go now, IMO. It just works and is extremely fast.


It's not going to take 15 minutes to understand WebPack and Parcel. Let's be a little more realistic. Sometimes you don't have the luxury of time and tools that you already know are going to get used, instead of new tools you don't.


https://parceljs.org/getting_started.html

If you have a use case as simple as the author is advocating, this only take about 15 minutes to grok. If it takes longer then you probably don't have enough front-end experience to productively contribute to this conversation. That is a little harsh, but the FUD in the JS world is incredible, mainly by people that have very little experience and understanding.


> a working Node.js environment

Sincere no-snark question from someone who's been out of the frontend game for a while: Why do I need Node in order to do "quick and dirty" frontend development?

(FTR I'm with you that jQuery is silly these days. Today's built-in web APIs do pretty much everything jQuery ever did.)


> Why on earth do I need Node in order to do "simple" frontend development

Because using current JS standards while moving the vast majority of the “make it work across a moving-target set of browsers” concerns to build toolchain configuration settings is a simplification from either explicitly managing all the compatibility issues and/or restricting to least-common-denominator JS features. Yes, build toolchains are themselves a source of complexity, but in net they can be a simplification.


Basically what Dragonwriter said. Without getting into the weeds of where webdev was and where it is now, we have made some massive progress. One of the huge improvements was moving to JS compilers (Babel/Typescript/Flow) that normalized features so all browsers going back to IE11 could be reliably supported with the latest language standards.

When you just sling jQuery on a page and try to use spread syntax or async/await, shit's gonna break.


Right, I get that. What I don't get is why Node is a requirement for a JS compiler. Is that just to get the runtime? I'd always thought of Node as a server on top of a V8 runtime.

(Thank you for your patience with this backend dev who finds your whole world very confusing.)


I had a similar jarring experience moving from C# dev to web apps. I knew I wanted to use building blocks available via npm. I went to download npm, and found the way you get npm is via installing node.js

Node js and the the package manager are inextricably tied together. Node js provides a local js runtime environment for the e.g. dev time packages to execute. It's also the api for interacting with the filesystem. Somewhere down there, yes, Node js is a web server, but it's kind of 'the' javascript execution environment for building local packages ("plugins"?) against.

The whole ecosystem is built up on javascript. If you're running grunt or gulp or webpack, it's all javascript. When you install packages globally they're put in a global folder. There are exceptions (I'm looking at you Cypress) that have native assemblies instead of js, but by and large there it's js, and it's stored locally. There are some pretty simple conventions (e.g. the 'node_modules' folder and the hidden '.bin' folder inside that) When running npm it feels like passing a one-liner javascript command into node's javascript repl/environment. The .bin commands are ambiently available.

It makes a lot of sense how it's grown organically... why there haven't been efforts to separate the constituent parts... I don't know. At some point maintaining the 'working thing' with <large degree of> complexity is easier than following a more rigorous, provable set of tools. I think it's a culture thing. Probably the same reason most of the problems are fixed by deleting node_modules and re running `npm i`


NPM was born out Bundler for Ruby. Node doesn't require you to use npm, but they are bundled together now. There are other popular registries like Yarn.


Node is required because that's what is used to compile the JS on the command line, it's a nodejs process. Once that's complete, any web server can serve the newly produced JS/CSS/HTML files.

JS is interpreted by the browser, but we compile locally so that the code produced implements workarounds for missing language features. The code produced is typically minified so that the payload sent to the browser is much smaller than it would otherwise be.

Node is analogous to Python, Ruby and PHP... they all can run webservices, power desktop apps and compile/build projects.


Yeah, I get all that too. I think my problem was that I sort of misunderstood what Node is. I've always thought of it as a web server, not a language runtime. So to me it seemed like using Node to run command-line tools was akin to doing

  python -m http.server my_cool_cli_thing
which is, of course, a bananas way to do things. But now that I've dug into it a little more I see that this is a misapprehension that I formed based on Node's original use case as an event-driven web server.

Thanks again.


Node is required for a lot of modern webdev tooling because (a) Node and NPM are usually bundled together and (b) people who write tools for JS development usually like to write the tools in JS too.


Quick and dirty should be a combination of Alpine and/or htmx.


Some people talk big about dropping jQuery and saving one request, yet they have a shipload of bloat elsewhere. Not using jQuery in and of itself is not an optimization of any kind. I use jQuery and my page has a perfect score in GTmetrix. If the goal is optimization, you have to consider the total package.

Addititionally, jQuery loads on the first request and sits in local cache thereafter. And it could already be in local cache if you use a CDN.


It won’t be cached already. Safari, Chrome and Firefox all have partitioned cache now.


I definitely agree with jQuery's legacy. We owe many parts of modern DOM and JavaScript to jQuery and Prototype.js (may I say that Prototype.js was to JavaScript what jQuery was to DOM).

There is probably no reason today to use Prototype.js, however, jQuery still is a better choice than React/Angular/Vue for small projects if the author prefers some syntactic sugar over plain DOM.


They loved it still in 2019. How about since then?


I'm the author of the post.

I was not expecting this to surface out of the blue 2 years later, so I had to go back and re-read what I wrote

I still stand behind what I wrote for the most part. If what you are looking for is not building a full SPA and you need compatibility with most browsers, for most users, then jQuery is still a very solid alternative.

A few things have changed however since then:

- As others have pointed out in the comments, a larger chunk of the Web has moved to SPAs, sometimes just because they wanted to build on the back-end something API-driven that can be reused for other scenarios (like mobile apps). The amount of apps that follow the more "traditional" model of server-side generation and then use JavaScript just to "augment" that experience is much smaller, but there's still a lot of use for them if you want to build something quick-and-dirty, like an internal app for your business. - Browsers are now implementing [cache partitioning](https://developers.google.com/web/updates/2020/10/http-cache...) which means that jQuery must now be re-downloaded by every website. It's still a rather small library, and compared with most modern apps the impact is negligible (average web page size is now [1900-2100KB](https://httparchive.org/reports/state-of-the-web#bytesTotal)). But this has negated one of the benefits of jQuery, the ability to serve it from a CDN that then is reused by other websites.

For a SPA, I would go 100% with Svelte as my first choice (but you may say I'm biased), but other frameworks are good too especially if you need to leverage existing skills on your team.


Right, not expecting this to surface out of the blue 2 years later, OP.

Thanks for the addition insights anyways


I'm not the OP.


Probably still. I don't think that that much has changed in the last two years.


I've depended on jQuery, not a strictly front end designer myself but have done a bit of client side dev the past 20 years.

If I had a choice, I'd go with one of the reactive libraries, I've used Vue. For me, if you're relying on Javascript IMO it gets the job done quicker.

It'd be interesting to see what jquery is used for in aggregation of all its usage. For me it was always selecting element(s) and XHR requests. With fetch (and a polyfill for IE), and the likes of querySelector it seems that a lot of the problems jquery solved have also been solved by the majority of popular browsers.

I say that as a layman of client side dev, happy to be corrected.


I've never been a UI dev, but have frequently been forced to put a UI as a PoC that becomes production UI. ugh. I had always turned to JQuery just for the browser compatibility aspect. I got out of the game for a few years and have recently gotten back on the that horse. I turned to JQuery as that's what I knew. Now that supporting IE is no longer a thing, and since modern JS essentially includes the missing pieces JQuery filled. I am slowly converting to plain JS in aims of removing JQuery.

I am awaiting my fetches with async functions in place of $.ajax with MDN pages in the next tab. Don't see how replacing one library of JQuery with another library like Vue/React/etc is any better. A crutch is a crutch by any other name.


>replacing

They're not so comparable TBH, the reactive element is the key difference. I can simply create logic, apply changes to the input data and the UI is updated. With jQuery you have to update the UI and data, far less easy. Point I was making is that if you're site relies on JS, I'd pick a reactive framework to do the heavy lifting.


You're bang on here. Why import an entire library when once polyfill and native features will serve you nicely.


JQuery is a tour de force of API design. Still use it in all my web projects.


NO, you can't use jQuery!! It's against the law!!! (proceeds to build non-interactive static page with create-react-app)

I find jQuery and Bootstrap great for fast prototyping. The thing I love about jQuery is the cross-browser compatibility. I know things have improved but I have very little faith in native JS "just working" as I would expect on all browsers.

But of course it was not designed for building reactive apps and so should not be used for that. It's nice just for fast-and-dirty UI interactions and animations.


It's really a great piece of engineering -- it a technical building block that is very well designed and solves a great number of problems. Some of the things that came later put development on a new level, but this doesn't take anything away from jQuery for the time it was made. Resig's book is in a large part "how jQuery was made" and it was a great read. Also some of the built in APIs that mimicked it like querySelector are not as elegant as jQuery, even though it was a solved problem at that point.


I am deploying Vue ui's now without webpack or any kind of bundler – jQuery and I have been through hell and back but I do wouldn't say I love it.


jQuery used to be (necessarily) bloated because it needed to support so many poorly-behaving browsers.

Now that these browsers are no longer relevant and support has been removed from jQuery, what is the performance hit, if any for using jQuery as opposed to vanilla JS?

I agree with many, I find the jQuery syntax to often be better than the alternative.


Jquery minified is 83KB. That's about the size of a compressed 300x300 px JPG.


> Although, at the time we weren’t really using the word “SPA”, and so we’d refer to that category of apps with terms like Rich Internet Application (RIA) or “Web 2.0 app”.

'Rich Internet Applications' were not the same thing as web 2.0 sites. Rather, they were a precursor to modern concepts like Electron and webview2.


> Then GMail came in 2004

OWA and Ajax appeared 6 years earlier. Why would Gmail be considered the milestone instead?


While the tools were available earlier, I think it's fair to say that GMail was most folks' first experience with a functional (while the content of the emails was still present, the point of GMail was reading and managing emails, rather than displaying their content) web app, rather than an informational one.

It seems a valid milestone, if not the first example.


Will never understand the snobbery against jQuery.

It was a great library for what it did and it holds up a lot of sites still.


jQuery is great, especially when you are low on time available and wanted to put together your product with minimal friction. VueJS, React etc. are great, but not when you have no more than 2 developers working. We are in the age of 5G internet and high bandwidth network streams, downloading a couple of hundred extra kilobytes of js files on mobile clients and desktop browsers should be no problem to at least 85% of the users.

Oh and BTW it pairs really well with StimulusJS. I've used it thoroughly and it's been a godsend


I guess it's easier to remember $ than queryselectorall . I recently realised most of its methods are now natively supported. I think people who don't use js a lot may not realise that.


in many ways jQuery has a lot of developer friendly niceties, in a different timeline jQuery became the new standardized DOM API and everyone would be happy


It's like with smoking. Sure, you're writing jQ for decade it's hard to quit. I strated coding relatively late and I have no fucking idea why do you ever need jQuery.


Any suggestions on a jquery-like easy to implement calendar control? That’s the one thing jquery still does better than everything else, at least that I know of.


Honestly I rely on input type=date nowadays


I recall people arguing that browsers should have jquery built in, because "it's clearly never going away"


I still think they should have just shipped jQuery or lowdash with browsers as a defacto JS standard library.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: