Hacker News new | past | comments | ask | show | jobs | submit login
You might not need jQuery (youmightnotneedjquery.com)
994 points by sfeng on Jan 30, 2014 | hide | past | favorite | 349 comments

I understand the desire for people to make pages like this (this isn't the first), but the examples are not completely honest with themselves, in my opinion.

One of the biggest benefits jQuery introduces is the concept of treating single selections and multiple selections identically. While using jQuery, I can emit a $(".class").hide() call, which will apply to all elements with the matching class. Simple and elegant.

However, using native JS as the page suggests, I will need to construct a loop within my function, especially if I'm using the DOM supported getElementsByClassName method, returns a pseudo-array of DOM nodes which don't have the style method available on them. You'll notice the examples already assume a selected element and leave much of this heavy lifting out.

Furthermore, jQuery offers the selection simplicities of Sizzle (ie: "#div .container .item). To do the same selection process in vanilla JS, I'll need to nest 2 getElementsByClassName functions in a getElementByID function, and return the concatenated results from each potential .container. That is to say nothing of more complex selectors.

So yes, if you're addressing the absolute simplest form of selection, this works, but otherwise I don't think it's really presenting the situation honestly.

You're certainly right. Did you see that the page specifically targets people who make javascript libraries? The page is arguing that when possible, libraries shouldn't depend on jquery, and shows how to do that for a few common idioms.

Since a library is written once and used in many different places, it's worth going to a little more effort to make it more flexible.

That sounds more like an argument for picking a canonical version of jQuery that can be cached aggressively, rather than everybody shipping a probably-buggy re-implementation of the 25% of jQuery they need.

This is actually a great example of the purpose of the site. Since IE8, browsers have supported a native 'sizzle-style' element querying syntax: http://youmightnotneedjquery.com/#finding_elements

IE9 and later also support a native each. You are correct however that you'd have to use Array.prototype.each.call, because the NodeList is not a real array.

It's still more complex, because you still have to iterate over it.

It sounds like you're looking for the querySelector and querySelectorAll methods: https://developer.mozilla.org/en-US/docs/Web/API/Document.qu...

querySelector and querySelectorAll could have been pretty great, but they suffer from some serious problems as they ended up spec'd.

The one I hate most is that qSA returns Yet Another JavaScript Collection That Is A Lot Like An Array But Isn't An Array And Therefore Doesn't Have Any Of The Nice Methods(TM). Yes, you're going to have to iterate over the thing using an index in a loop.

There's others:


I'm really not sure how the standards-makers got this so terribly wrong given that the libraries had already started to solve the problem.

    Array.prototype.slice.call(document.querySelectorAll('.myClass'), 0);
Or if you want to abstract that into a utility function:

    function qsa(sel) {
        return Array.prototype.slice.call(document.querySelectorAll(sel), 0);

    qsa('.myClass'); // Returns array of elements

And now you are on the way to rewriting jQuery from scratch.

Add a few more helper functions, separate it all out to its own js file, reuse the js file in other projects, and soon people will complain about the bloated js file you keep using in your projects.

Man, I really do enjoy my chosen line of work. It creates such fun things to debate over.

Elements is supposed to fix this:


But AFAICT isn't implemented anywhere, which makes it not that useful. Perhaps a polyfill could be done.

> However, using native JS as the page suggests, I will need to construct a loop within my function, especially if I'm using the DOM supported getElementsByClassName method, returns a pseudo-array of DOM nodes which don't have the style method available on them. You'll notice the examples already assume a selected element and leave much of this heavy lifting out.

You don't really need jQuery for that, though. You just need a forEach-like function that works with NodeLists. This is easily implemented in three lines of JavaScript.

> Furthermore, jQuery offers the selection simplicities of Sizzle (ie: "#div .container .item). To do the same selection process in vanilla JS, I'll need to nest 2 getElementsByClassName functions in a getElementByID function, and return the concatenated results from each potential .container. That is to say nothing of more complex selectors.

Not since IE8. These days, you can just do document.querySelectorAll('#div .container .item'). For most common selectors like the one you showed, Sizzle ends up delegating to this method anyway. You only need Sizzle for selectors that cannot be expressed in CSS (e.g. "select a UL with only one child", which would require the CSS4 ! marker).

Those sort of selections are not specific to jQuery. Most DOM libraries have had them for a while, and browsers (IE8+) have provided it for some time as well in QSA: https://developer.mozilla.org/en-US/docs/Web/API/Document.qu...

In practice a better approach would be to build up a micro-library of functions to just implement the small subset of features you do need.

  // Using underscore/lo-dash and ES6.
  _.forEach(document.querySelectorAll('.class'), elem => elem.hidden = true);

  // Building reusable utility functions
  function forEachSelector(sel, cb) { _.forEach(document.querySelectorAll(sel), cb); }
  function hideElement(el) { el.hidden = true; }
  forEachSelector('.class', hideElement);
Of course, there is the danger of ending up with homegrown jQuery that is less well tested and less well thought out. Perhaps there is a place for a small JS library that works with native DOM elements, in the same non-invasive way lo-dash and underscore work with data structures.

The problem with jQuery is that it's an all-or-nothing approach. The way it wraps native DOM nodes means it keeps trying to pull you back to using its inbuilt utility methods.

> The problem with jQuery is that it's an all-or-nothing approach. The way it wraps native DOM nodes means it keeps trying to pull you back to using its inbuilt utility methods.

Not true at all. You can do a custom build and leave out things you don't need. You can even leave out stuff you DO need and replace with your own simpler shim. See the README file.

Sure, it's technically possible. But not common from the projects I've seen.

The APIs seem to be designed with the assumption that all your code will be using jQuery. For example converting a wrapped node to a native DOM node requires an extra call that, in my opinion, is ugly: $('.something').get(0); and could be considered to be an anti-pattern.

I don't think this is a bad thing. jQuery does a good job at providing a DSL that replaces native DOM access. But if you want a library instead of a framework its strongly opinionated style can be off-putting.

> The APIs seem to be designed with the assumption that all your code will be using jQuery.

Again, not true. For example, the `this` in an event handler is the actual DOM element, not a jQuery object. Whether you handle that directly with DOM methods or wrap it with `$(this)` is up to you. Many people prefer the latter but the former is often smaller and prettier.

> For example converting a wrapped node to a native DOM node requires an extra call that, in my opinion, is ugly: $('.something').get(0); and could be considered to be an anti-pattern.

How common is that, really? Your example assumes a single element with that class name. Why not chain a jQuery method behind it and handle the 0 or N cases as well?

Or even better, if you're only selecting one DOM element that doesn't need the jQuery wrapper, then don't use jQuery for that one case. There's nothing that prevents doing that even if jQuery is being used for other elements in the project.

Just because jQuery is loaded doesn't mean you have to use it for everything on the page.

I agree with most of your points.

However, your Sizzle example is covered by document.querySelectorAll: https://developer.mozilla.org/en-US/docs/Web/API/DocumentFra...

"You might not need jquery"

The Bad:

The premise of the examples list seems a bit disingenuous.

Very few of these things take into account the full convenience of jQuery. It's much more than saving a couple lines of code or knowing the native way to accomplish the most basic version of a task. jQuery's real benefit is preserving simplicity as your needs grow more complex.

Right off the bat I feel like the getJSON[1] example is a bit simplistic. Almost anyone using ajax needs to serialize data, handle errors, prevent caching, etc. jQuery has thought about all this[2].

Don't get me wrong -- most of my work has been without jQuery, but that means I know exactly how much work it is.

The Good:

The format is a nice way to show people (who really don't know otherwise) the native JS plumbing.

"The number of people who don't know that jQuery != Javascript is too damn high". So to help combat that, I really appreciate the idea behind this site.

It's great to show side-by-side how jQuery isn't "magic", since many people seem to learn jQuery these days without even knowing the first thing about Javascript, but I just think it should be presented with a slightly different premise.

[1]: http://youmightnotneedjquery.com/#json -- side note, why did they set the handler after the `send`? It seems like that could cause problems if the result was returnable quickly, such as from cache, though I haven't tested it.

[2]: http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings

That's a great point - this is really awesome as a "learn the essence of what jQuery is doing for you!" and a little annoying as a "you don't need jQuery!".

I took the tone as being directed to people publishing plugins that use jQuery for 1% of its functionality, forcing people not using jQuery to either not use that plugin, rewrite the plugin or include jQuery.

Edit: it actually literally says it's for library developers.

For 1, I was wondering about that too - it seems like such an odd thing to do. Who knows what the latest JIT-y stuff and cached responses could do to how fast things run? Just set it before you send, like any normal developer would, and get rid of the need to worry about it.

right off the bat its wrong, IE8 doesn't include JSON support unless you're in strict mode.

You have it a bit backwards, IE8 doesn't include JSON support when you are in quirks mode, which no modern application should ever be in.

should is the most important word in that sentence : )

No, quirks mode is triggered by the developer not including a doctype. If you include a properly formatted doctype, you will have JSON support in IE 8.

>post-IE8, browsers are pretty easy to deal with on their own.


- CSS browser prefixes are automatically inserted by jQuery

- Many jQuery selectors don't exist in the CSS selector specification

- Looks really really ugly and that makes it hard to read for you and other coders.

    var pairs = $(".form").not(".old").serialize();

    /* without jQuery */

    var pairs = [].slice.call(document.querySelectorAll(".form"));
    var data = forms.filter(function(ele){
      return /\bold\b/.test(ele.className);
      var form = ele.querySelectorAll("select, input, textarea");
      var pairs = [].slice.call(form).map(function(subele){
        // maybe if subele.type === "select"
        // but I got tired of writing this example
        // but that's the point anyway
        return subele.name + ":" + (subele.value || "") + ";";
      return pairs

    }).join("").replace(/;$/, "");
So be kind with your co-workers, use jQuery. Even my 5 year old android can run jQuery without freezing the built-in browser.

> Looks really really ugly and that makes it hard to read for you and other coders.

This point might have been better made if you hadn't intentionally structured it to be as unreadable as possible, and also shoved in a few lines of comments to pad it out and make it look bigger than it needs to be. Not a very honest example at all, considering native JS can be as readable as you want to make it.

> So be kind with your co-workers, use jQuery. Even my 5 year old android can run jQuery without freezing the built-in browser.

My co-workers can read and write native JS with or without jQuery as it is, why is it being _kind_ to avoid writing in the style of the native language?

> Not a very honest example at all, considering native JS can be as readable as you want to make it.

Can you make an honest version of the example? (genuine interest, no sarcasm)

Expressiveness means you waste less of people's time and mental effort.

    $(".enemy").after('<div class="crash">').remove()
Without jQuery:

    var enemies = document.querySelectorAll(".enemy")
    for (var i = 0; i < enemies.length; i++) {
        var div = document.createElement("div");
        div.className = "crash";
        enemies[i].parentNode.insertBefore(div, enemies[i]);
Here the last one is comprehensible but even then, it takes longer for a programmer who just found it to figure out what it is doing; and, caring about other peoples time (and future yours) can be referred as 'kind'.

First off, when using jQuery you are still coding in the native language.

Second, the many debates that have happened on HN it is quite clear there is no set "style" in coding Javascript. My style of coding in the native language may be quite different than your style. Therefore, if you use your style in a verbose manner because you choose to not use jQuery and I use my style in a more concise manner because I am using jQuery, it could be said the more concise method is kinder to someone following behind.

But like all things considered a style, opinions vary.

No, please no. If size is an issue for some reason or you want to have no dependencies you can use something like http://zeptojs.com/ and just embed everything in one minified file. If you do things right only the functions you are actually using will get placed in there as well.

Do not reinvent the wheel to solve problems that can't be solved in much cleaner and nicer ways. Managing dependencies can be annoying, but we all bite the bullet for a very good reason, because reusing solid well tested code is a good thing.

I believe the point is that many libraries use about 1% of jQuery. That hardly justifies pulling in the entire thing.

A personal anecdote: I recently un-jQueried a little piece of code and ended up with only a couple lines of extra code.

Certain parts of jQuery are heavenly and well worth it, but really basic usage doesn't actually save that much. $("#something") instead of document.getElementById("something") is not really buying you much in the way of cross platform-ness or thoroughly debugged code and is hardly reinventing the wheel.

I agree with the overall message- you should be thoughtful with all your dependencies. You should only add complexity when it makes sense.

However, the author goes beyond just selector vs. getElementById().

Does the way the author uses XMLHttpRequest work in other browsers the way it works in IE? I honestly dont even remember anymore.

How about the code for fade? I never even knew the details of this feature. And I'm not sure I want to.

Funny, because IE invented XHR.

For IE9, don't you need IE-specific code for cross domain requests?

Yeah, you need XDomainRequest for CORS requests in IE8 and 9. IE10 is fully standards-compliant.


It is very castrated, better to use hidden iframe + window.postMessage for cors in ie8 and ie9.

I don't think "castrated" is the word you meant :-) Perhaps "constrained" or "restricted"

...why not?

"to render impotent or deprive of vitality"

For fading, I recommend just adding or removing a class and let css transitions do the job. If you dont mind it not working in IE8 of course

and IE9: http://caniuse.com/css-transitions.

Pedantry aside, your point stands, CSS transitions can use the GPU and degrade gracefully.

Considering XMLHttpRequest is what other browsers used before IE caught up, I assume it does work the way you'd expect across modern browsers. I'd have to check the standard and IE8+'s conformance to the standard to be sure. That's what this post is really about for me, reminding that modern browsers follow a standard that allows for getting rid of most of jQuery. Reading it also made me recall a post from 2005 by PHP's creator: http://rajshekhar.net/blog/archives/85-Rasmus-30-second-AJAX... (Note IE uses ActiveXObject.)

XMLHttpRequest was first introduced in IE5. I think in retrospect MS regrets its introduction, but that is another discussion entirely.

As I recall, they specifically implemented it in order to facilitate Outlook’s web interface – their collective regret may be tempered by the satisfaction they got from all those high-margin site license sales to which that feature contributed.

I wouldn't mind hearing a snippet of that discussion. Why would MS regret XMLHttpRequest?

Microsoft twiddled its thumbs while the web grew up and around Windows using the technology the company introduced.

That makes complete sense. Never thought of it that way.

For me jquery is all about events. Making sure I get the event tree bubbling in the correct way across the entire universe of browsers and all its data being normalized is such a time saver. Even their support isn't perfect, but I'm sure its way better than any other event library out there in terms of breadth and depth of testing. The selectors bit is a nice to have, but that is getting easier since its inclusion in dom itself.

Since I code mostly in clojurescript in my home hours any functional idioms from jQuery I no longer use. A long time ago jresig joked about making an oo form of jQuery. It's not that funny now, as it might be slightly easier to wrap an object based lib for all the various compile down to js languages (typescript, coffeescript, clojurescript, scalajs, etc)

About one year ago, I developed a shared widget. Some fraction of my clients refused to load jQuery, as they still preferred older, less popular DOM libraries.

Starting with jQuery's battle-tested event handling code, I trimmed features unnecessary for my widget: event.data, IE7 support, consistent focus events. I replaced jQuery's indispensable descendant selector feature, formerly jQuery.delegate, with a simple conditional in my event handlers. (e.g. Walk parentNode references from event.target, looking for a class name.)

I was left with about 75 lines of code in my DOM abstraction library. I preserved jQuery's tricks for Microsoft's attachEvent and Safari's text nodes. About 15 lines were dedicated to normalizing attributes. My polyfills for preventDefault and stopPropagation were about 10 lines each.

It's amazing how far native DOM has come in recent years.

If you are looking for a standalone event (delegation) library check out one I wrote http://craig.is/riding/gators. The syntax is very similar to jQuery.

Two things:

1) The minified jquery script is ~100kb, for a script that is loaded once per website that's pretty tiny. Especially when you consider the fact that the latency involved with opening the network connection to fetch the file will likely exceed the time required to pull the file down. Once you've initiated the download the difference between pulling down 20kb and 100kb isn't all that much.

2) You can use the google jquery file reference. That means a big % of your site visitors will already have the cached script in memory, and for those that don't the download will be pretty speedy given that it can be fetched from the google domain in the background (while the rest of your site assets are being fetched by the browser).

It might be the most cached file on the internet. Pulling jQuery is hardly expensive. Especially if you're pulling it from the google cdn.

Caching or CDN does not help in squeezing out JS performance (actual JS execution and not n/w performance)

You think that a page that loads jQuery but doesn't use most of it incurs a performance penalty? I'll grant there are a few initializations and dom checks that jQuery does, but it probably blocks for all of 20ms.

...which is significant.

20ms is significant?

Think of it as a fifth of your time budget spent doing nothing.

Most modern browsers are able to paint while loading script files, especially if you put your script files at the bottom of the page, where they belong. So, no, 20ms of parsing, compiling, and a small amount of execution is not a lot of time. Period.

caching won't help for libraries that want to have a particular version of jquery baked in ...

> I believe the point is that many libraries use about 1% of jQuery. That hardly justifies pulling in the entire thing.

Sure, but if you use a few libraries that all use a couple features of jQuery you still only need to load jQuery one time and everything just works. You may not care if it only works on the most modern browsers, but someone who uses your library probably will.

Or you need jQuery two times because one of the plugins you need is not well maintained and depends on an older version. This actually happens.

$('#something') and document.getElementById('something') are not quite the same thing because of what you'll do after you create that reference.

document.querySelectorAll() uses the same kind of syntax for selectors as jQuery.

And requires IE 9+ which rules it out for a lot of people...

Actually, no. IE8 supports it.


IE8 is limited to the old CSS selectors so basically it sucks and doesn't really support it.

In practice, especially for javascript usage, the old CSS selectors cover all the bases.

The new-stuff, while great for styling, isn't all that relevant for scripting. nth-child, say, is often (though not always) simply an indexing operation on the return value of querySelectorAll; and in general you don't even want that since usually you have a specific element in mind and have labelled that element with a class to find it.

I don't support IE8 anymore, and use CSS3 liberally in the actual css, yet I can't think of more than a handful of cases I used the selectors from javascript, certainly none of them critical. Do you actually use this?

But so is all of the actual CSS in your app.

and support only a limited subset of the selectors jQuery supports.

> $("#something") instead of document.getElementById("something")

or even just document.querySelectorAll("#something")

You lose some browser compatibility with qSA, whereas gEBId works everywhere. You need IE8+ for qSA, and you need to ensure the page isn't in quirks mode. If you're OK with that then you can also do: var $ = document.querySelectorAll.

Probably best to do this within a closure so that you're not hijacking any jQuery instances that may be on the page.

Would just like to point out that, if you are using a commonly used CDN, jQuery/Zepto will most likely be cached already in the browser.

So why not break up a large library into smaller useful pieces. Why can't we import only what we need.

You can create a custom build of jQuery and exclude specific modules: https://github.com/jquery/jquery#modules.

1) Zepto is POS. It offers the illusion of jQuery compatibility while delivering only maybe 80% of it. You simply cannot reverse-engineer something 100% without doing everything the original does, so you might as well use jQuery.

2) In 2014, jQuery feels like it is the wheel reinvented. I'm looking at the jQuery API modules now and here's what I consider jQuery is still useful (as in nontrivial to replicate):

  - AJAX (Too many cross-browser differences in XHR/XDR implementations)
  - Event delegation (Too many cross-browser differences in what gets triggered/bubble/cancelable)
Most things in jQuery may only save you a couple of keystrokes to a few lines of code. For everything else, you can drop in a small library / polyfill when needed to get back something like $.Deferred or the $.fn.serialize() or $.fn.val(). In fact, there are already many small libraries that aim to do just one thing only and do it well.

3) You never need all of jQuery. If you need all of jQuery, you are doing it wrong. I don't even want to look at your giant pile of procedural, chained-20-times-for-every-element hourglass-shaped callback pasta.

4) The plugin ecosystem is horrible. This might have to do with the fact that jQuery doesn't give you any help other than a namespace. Most plugins come with ginormous pile of options and/or very rigid and opaque HTML/CSS structures. Most of them don't come with tests, are extremely buggy and very very hard to tweak.

5) jQuery is extremely slow. Its slowest parts are creating the context because of Sizzle and event delegation. My recent PR for Backbone to make jQuery optional in its View is around 70% faster using all native DOM methods.

6) jQuery was born in 2006, when IE6 still had 70% of market share. jQuery's many layers of smooth-overs come at a very high performance cost, and it doesn't even smooth things over that well. There are still many edge cases in event handling such as triggering a click that bubbles on a detached element on Webkit that jQuery just can't do for you. Shouldn't you aim to provide the best experience for the 50-80% of users out there who are on modern browsers instead of a mediocre experience for 100% of them?

> jQuery was born in 2006, when IE6 still had 70% of market share. jQuery's many layers of smooth-overs come at a very high performance cost, and it doesn't even smooth things over that well. There are still many edge cases in event handling such as triggering a click that bubbles on a detached element on Webkit that jQuery just can't do for you. Shouldn't you aim to provide the best experience for the 50-80% of users out there who are on modern browsers instead of a mediocre experience for 100% of them?

Ignoring the Webkit example and focusing on IE, isn't that what jQuery 2 is for?

Nope. jQuery 2 just removed code for IE 6/7/8. Nothing was added. Code sized reduced, but almost the same performance. My benchmark shows only 10-15% improvement. That's nothing compared to using the DOM API straight up.

Care to substantiate your benchmark where you compare jQ1, jQ2, and the native DOM API?

Here is the mentioned pull request: https://github.com/jashkenas/backbone/pull/2959

Here is his benchmark: http://jsperf.com/backbone-patch-22be8f9/2

It only compares jQuery 1 and the DOM API, no jQuery 2.

    TestBaseView: DOM API
    TestPaulView: Reduced jQuery usage
    TestView: jQuery

Hmm, I'm wary of a test that involves another framework to test the underlying jQ v. Native DOM performance difference. I'd be much more comfortable eliminating Backbone from the equation.

Also, this is just one test - wyuenho's claim was for jQ vs. the DOM in general, which is a much broader claim than an unknown subset of functionality.

I don't doubt that native DOM methods are faster than jQ, but I like claims to be backed up by evidence.

The evidence is in the form of an experiment repeatable from your browser's dev console. Play with it.

If you hand me some code to run, I'll run it. Otherwise my test risks not being the same one that you used to make the claim.

The onus is on the person making the claim, not the person trying to verify it.

Isn't the code to run here[1]?

[1]: http://jsperf.com/backbone-patch-22be8f9/2

See my previous comment[0]. That perf test is testing Backbone's use of jQ vs. native DOM, not jQ v. DOM in isolation. I don't trust that there aren't side effects and interactions in the test.

[0]: https://news.ycombinator.com/item?id=7155710

Yep that's it. You can replicate this benchmark and replace jq1 with jq2 to see how much faster it gets. You'll be disappointed.

>> Shouldn't you aim to provide the best experience for the 50-80% of users out there who are on modern browsers instead of a mediocre experience for 100% of them?

In my experience, this decision is not as cut and dried as you make it seem. But I don't work for a startup, so take that for what it's worth.

I love the idea of removing Backbone's jQuery dependency. If I could use Backbone without jQuery, I would gladly leave jQuery behind.

For my use case, Backbone would also have to lose it's jQuery dependency for RESTful model persistence, but maybe that means I should get to work on it and submit a PR :-)

> I love the idea of removing Backbone's jQuery dependency. If I could use Backbone without jQuery

You can the only hard dependency of backbone is underscore.

You can just replace Backbone.ajax yourself. There are many $.ajax drop in replacements out there that you can use.

Check this fork of backbone out:


jquery is really just an abstraction for dom, it is not an api for application building. When I have to use the dom, I definitely turn to it. I'm not sure why people object to having additional helper functions in jquery for a measely 100k or so.

You don't have to use plugins you know, its not a law.

Because 100k is not measly, it is huge. And jquery is hundreds of times slower than the perfectly fine native methods.

Whether 100k is huge or not depends on the project's requirements. In some cases it's perfectly fine, in other cases it's a problem. Such a broad statement cannot be supported.

Much the same; even if jQuery is that much slower it can sometimes provide something that overcomes the slowness factor. It varies from project to project. Especially if the project scope practically requires you to rewrite jQuery from scratch, you might as well use it.

100k is huge, period. Whether or not a huge dependency is acceptable depends on the project. Yes, we know it depends on the project, that was the point of the site. The whole point is "if you are making a library, and don't really need jquery, please don't force that extra dependency on users of your library".

Fantastic point. Abstractions can be dangerous because they often aren't developed right.

But that isn't the case here. When something like jQuery comes along, hiding so many gory details, and has been tested to death both in development and in production use all over the world, we are all better off because we remove so much failure surface area from our code.

Browsers of the world, please embed, compile and cache last few versions of JQuery upfront. That's gonna speed up the whole navigation experience.

As near as I can tell, browsers are already at least sometimes caching compiled representations of JS; the win from shipping specific versions of jQuery would be minimal, and not work unless you used specific CDNs anyhow.

The question is, how many of those gory details still exist in modern browsers? There's not much to test if you're just calling el.classList.add().

More to test than you thought. That just broke more than 20% of the Android installed base, since Android 2.3 doesn't work with classList.

A classList polyfill is like 500b compressed. No need to blow a non-existent problem out of proportion.


are you serious ? thats actually a good example on why you should use jquery. First of all the dev needs to know exactly on which platforms he will run into problems and how to solve them...And what if you need not one but several polyfills ? That gets messy pretty quickly.

Ah no. First of all, you should always know which platform you target and what works and what don't work on those platforms, even if you are using jQuery. jQuery is not perfect. Platform specific corner cases are still exposed to you.

What if you need several polyfills? Drop them in too. You should always know what browser feature you are using. The same argument goes for using libraries. What if you need more than jQuery? Bring them in too. There are asset pipelines and/or pure front end packaging solutions like AMD to help you. What's the problem?

> You should always know what browser feature you are using.

Why? If I just drop jQuery in and treat that as my API baseline, what do I lose? A little performance, a few hundred kilobytes' download (almost certainly cached from a CDN anyway). And it frees me up from remembering a bunch of corner cases and keeping track of a bunch of implementation details, letting me focus my attention on more important things.

You can certainly use JQuery as your API base if you're willing to take the hit on performance and a few hundred KB download, and are willing to take that hit on every project you write.

The problem is that this shuts you out of a lot of hot, emerging markets that can be quite lucrative. You will never work for Google (as a front-end engineer) if you only know JQuery and not the native DOM APIs. Your mobile HTML5 apps will suck and will lose out to native counterparts in the app store. You're at a disadvantage in any competitive web market where people bounce from the website if it's too slow (there are more of these than you think).

If you're willing to limit yourself in this way, sure, go for JQuery. There is still a pretty booming market for Intranet apps or progressive-enhancement mostly-static sites where JQuery is just fine, and it provides a nice productivity boost for those use-cases.

The advantage of polyfills is that they give you flexibility and let you push the edge of technology today, and then they don't become obsolete tomorrow. As the web evolves you just get rid of the polyfill and you already know the latest & greatest of tomorrow. That lets you push into the emerging new markets that can be quite lucrative, at the expense of actually learning the (sometimes hard-to-use) APIs on the bleeding edge.

That makes a lot of sense especially in areas where you are competing for people's attention. If you aspire to being a front-end engineer it'd be silly not to know the DOM APIs inside and out, especially now that browsers have such nice dev tooling.

But for those aspiring to create big things another approach is to find a niche where you can offer something exclusive that people want. Thefacebook offered something that students would have put up with > 1s load times to see that they couldn't reliably get anywhere else. http://en.wikipedia.org/wiki/File:Thefacebook.png

The point is, jQuery doesn't free you up from remembering lower level details, they are still there in your face all the time, especially when it comes to event delegation and handling. jQuery also doesn't help you with CSS, which is even more of a pain than DOM inconsistencies. The whole point of polyfills is to patch browser incompatibilities, often times without losing any performance to newer browsers, so you can provide the best experience to half the people in the world on newer browsers and a mediocre experience to the rest, instead of a mediocre experience for everyone. If you care about attention to details, you should understand what your browser is doing. Polyfills are things that you only have to learn once and drop in once. Isn't providing a good experience one of the more important things?

Actually, jQuery can help with CSS inconsistencies, much the same way vanilla Javascript can, if you have the mind to use it that way.

You seem to be laying much of the "mediocre experience" on jQuery in this case. I would like to know why you feel this way. Seems to me that loading in polyfills for every browser inconsistency can lead you to the same problems you feel exist with jQuery.

I don't just care what my browser is doing, I care what all of them are doing; which often leads to using jQuery. Depends on the project and the number of expected browsers involved.

Polyfills are things you learn once and drop in once? So is jQuery.

What if the best experience to be provided suggests using jQuery? Would you use it?

All in all, to use or not use jQuery often depends on the project. If it fits, use it; if it doesn't, don't use it.

...Which is an argument in _favor_ of jQuery.

You silly goose!

And style.display='block' for jQuery.show() does not work with <tr>'s (which need 'inline-block') and rules which have an !important clause in the CSS (which need to first set the display to empty string and then set it again).

Define "modern"? IE8? Older Android browsers? How much compatibility are you willing to give up?

Size really is issue when dealing with mobile devices. Even from disk cache each KB increases startuptime by about 1ms (and jquery 2 is ~32kb minified, for < 2.0 lot more). Over cellular connection you can nicely multiply each KB by 100ms. This is even worse when you minify and concat your JS library dependencies, as most likely your cache headers expire way too fast for them. If you have bothered to set them at all.

Also, last time I checked jquery uses "querySelectorAll" for that fancy $("selector") syntax, which is slow as hell with every possible browser compared to "getElementBy*". This might not be issue with desktop machines, but you will probably lose most of your mobile users because of that. Jquery does also exposes very dangearous things from the API. For example: most of the time use of css modifying from JS just implies that your UI logic is fundamentally flawed (also, incredibly slow as poking CSS from JS will force full relayout which will make your mobile users throw their devices to wall or leave your site).

Jquery lets people cut corners which will give short term benefits, true. But in long term you are just killing your user experience. And like others said, people mostly use like 1% of the API, which has as easy native browser support.

The speed difference between querySelectorAll and getElementsBy* is entirely because of the difference between live nodelists and static nodelists. getElementsBy* returns a nodelist that reflects changes in the DOM in real time - this means that it's just returning a pointer. querySelectorAll copies the full result set into an array-like object at method-call time.

The flip side of this is that iterating over a querySelectorAll nodelist is significantly faster than iterating over a getElementsBy* nodelist. You really don't want to call .length on a getElementsBy* nodelist, because it's O(N) and has to traverse the full nodelist. .length on a querySelectorAll nodelist is just a field lookup. That means that when you combine the original call with one iteration, you're usually about breaking even with querySelectorAll.

Also, setting CSS properties doesn't for a full relayout; it just sets a dirty bit and the property. Setting CSS properties and then querying the DOM causes a full relayout. Unfortunately JQuery often does the latter in .css, which makes it slow as molasses. You can do direct .style manipulations all you want with very little performance penalty though.

> Also, last time I checked jquery uses "querySelectorAll" for that fancy $("selector") syntax, which is slow as hell with every possible browser compared to "getElementBy*".

Not true, and has never been true; maybe you confused jQuery with Zepto? "#id" uses getElementById, ".class" uses getElementsByClassName, more complex selectors go through querySelectorAll, and custom selectors through Sizzle.

> And like others said, people mostly use like 1% of the API, which has as easy native browser support.

Hard to argue with that statistic since it's made up!

> Also, last time I checked jquery uses "querySelectorAll" for that fancy $("selector") syntax, which is slow as hell with every possible browser compared to "getElementBy".

I seriously doubt you ever "checked". You would know that jQuery's selector engine (Sizzle) is optimized and uses getElementBy* when it can. You would also know that every browser has bugs in querySelectorAll, and jQuery's selector engine detects the bugs and routes around the browser bugs.


How complicated your query have to be to run into these QSA bugs? Don't forget that you are paying a very high performance cost for compatibility. I mean, how many people are still on Chrome 21 and Firefox 3.5?

> Over cellular connection you can nicely multiply each KB by 100ms.

This cannot possibly be true. Do you have some data to back it up?

jQuery might use querySelectorAll for its selector, but also looks for basic patterns and optimizes them by using things like getElementBy* eg. $("#test") will use getElementById behind the scenes, not querySelectorAll.

In most cases where you have any level of complexity, you are better off using jQuery or some other already tested out libraries. That being said, blanket statements about technology choices are suspect because every project has different needs and requirements. You should evaluate things on a case by case basis.

If you're creating a simple brochure website for a small business and literally just need to show one hidden element on a click or do something else very simple, there's a legitimate argument to avoid jQuery. It depends on the level of complexity you need.

The web is filled with unnecessary bloat and I'd like to get rid of some of that.

It's better if libraries don't just assume jQuery is everywhere, because I suspect those days are ending. Apps built on newer front-end frameworks like Angular and React might not need it, for example.

As a library author it's becoming more important to think case-by-case -- use raw JS if you just have some simple selections or XHRs, or use Zepto/etc if that covers you, and only depend on jQuery if you really need its richness in your lib.

So in that spirit, I appreciated the article.

> Apps built on newer front-end frameworks like Angular and React might not need it, for example.

Well, Angular has jQuery (lite) built in.

It has a jQuery-mostly-compatible node wrapper built-in, which is why it doesn't need jQuery.

Which is both good and bad in that it also modifies jQuery's internals if it's present. (I last looked at the 1.0.x branch)

If it's just a general library to use anywhere, then sure build it with no dependencies.

But if it's a library intended for Angular then the library would be built with Angular as a dependency, much like it would be with jQuery.

I don't see a negative with a library being built that has dependencies if it is intended to be used in conjunction with the thing it is depending upon, since in most likelihood a like-minded developer is already using it.

If you like spirit, you'll love this: https://gist.github.com/rwaldron/8720084#file-reasons-md

You do realise zepto works in IE10+ only, and even then you need an additional module for support. I wouldn't say it's worthwhile. It is not a viable alternative.

I'm working on a widget that other people will embed on their page. I cannot make assumptions about jQuery being available and I cannot afford to add jQuery as a dependency. Assuming the widget was valuable to you, would you want to add my widget to your page if it included 94kb (jQuery 1.10.2 minified) of JS before my code was even added on top? If you cared about performance, it's highly unlikely you would.

So for that reason I've been working with plain JS for months now. We have browser support back to IE9 (maybe even 8), and our entire codebase is around 25kb minified (gzipped < 6kb). We have one or two collections of utilities, but most of it is application code that would still be there even if we had jQuery as a dependency. All I can say is it is not that big a problem. If you're not sure how to get something to work across browsers, look at the source of jQuery (this website [0] is fantastic for this purpose) or any other library that is well regarded.

But you know what? Most of the time it isn't even a problem. And with modern tools [1][2] and a good test suite, it's not difficult testing across multiple browsers to quickly find issues.

Before even working on this project I decided to go on a self-administered "jQuery diet". I haven't used jQuery in any personal projects [3][4] for at least a year and it's great. It took a little adjusting, but not much. If anything it was a little shocking. I thought I was a good JS dev, but it really opened my eyes to how little I knew about the DOM and other native browser APIs and, honestly, I felt a little ashamed.

Conclusion: sometimes going it alone is the right decision. jQuery is absolutely the right choice in some environments, but it doesn't make it the right choice absolutely

[0] http://james.padolsey.com/jquery/

[1] http://karma-runner.github.io

[2] http://vanamco.com/ghostlab/

[3] https://github.com/WickyNilliams/headroom.js

[4] https://github.com/WickyNilliams/enquire.js

Isn't the point here that JQuery is reinventing a lot of core JavaScript stuff? It isn't reinvention if it is already there.

JQuery has down sides other than size. There is also maintenance, dependency and backwards compatibility issues.

EDIT: Plus it adds a lot of extra syntactic mess, extra () $ and .

You don't need an abstraction to do something that's natively implemented on your platform.

No thanks, I'll take something that I'm sure 99% of web developer know by heart and works cross browser. I don't want/need to spend hours upon hours writing "clean" code that doesn't use jQuery. I have business problems to solve.

That's what it all boils down to... "I have business problems to solve".

Abstractions are meant to, well, abstract an implementation. You might very well want to abstract a native operation for a bunch of different reasons. You don't need to, but maybe you should.

For example,

is quite more readable than

  el.style.display = 'none'
. And I'm not even talking about the other advantages.

> $(el).hide()

> el.style.display = 'none'

You meant something more like

    document.querySelectorAll(el).forEach(function(e) { e.style.display = 'none'; }
and a polyfill for IE8 due to lack of native Array#forEach, right?

This equivalency only works when el is a DOMElement, not a selector string.

Which one is likely to be more common?


   el.hidden = true;
in modern browsers

The documented semantics of the hidden attribute say otherwise https://developer.mozilla.org/en-US/docs/Web/HTML/Global_att... http://www.w3.org/html/wg/drafts/html/master/editing.html#th...

" it is incorrect to use hidden to hide panels in a tabbed dialog, because the tabbed interface is merely a kind of overflow presentation — one could equally well just show all the form controls in one big page with a scrollbar"

I'm curious - is this spec'd anywhere? I just tried it in Chrome and it works great, but I couldn't find it in any of the specs for Element or Node.

According to specs mentioned elsewhere, it seems to have reasons to exist other than just display hide/show purposes.

It's easily overridden by CSS.

el.style.display = 'none' pretty much works everywhere.

To me, it seems to depend upon what the purpose of hiding/showing the element is in specific cases.

Right, because why have "var x = 2+2" when you have perfectly maintainable assembly!

I think the point is that "$.contains(el, child)" is not a useful abstraction of "el.contains(child)".

You wont have $.contains, instead $(el).children(child) returns a chainable filtered list of the first level of child nodes, or $(el).find(child) will go down recursively.

jQuery rarely dumbly duplicates some native functionnality, as for the example above, most of the time it will diverge in meaningful ways.

These two new functions you mentioned are both in the article linked to above. 'el.children' and 'el.querySelectorAll(selector)' are given as alternates. It is true they aren't 100% the same but JQuery isn't different enough in my opinion for there to be any clear reason to use it instead of what is already available.

As a side note, I know this is totally a matter of taste but "chainable" in the JQuery sense reads to me as "spaghetti generator".

> As a side note, I know this is totally a matter of taste but "chainable" in the JQuery sense reads to me as "spaghetti generator".

I think this is more important than a side note. The reason jQuery's 'children' or 'find' is way better in my eyes is because of the support for arrays as target and argument, and the possibility to pass the resulting collection to the next command as is.

Going the native route, filtering the children will need an extra loop, doing so on an array of parent elements will also bring an other loop. And we'd have to deal with a Nodelist instead of an array. A 2 command jQuery line would be 5 to 10 lines in native code, every time there is some node tree to filter.

Manipulating collections of DOM elements is such a common case that having to deal with loops every time is just tiring, less readable and more prone to basic errors.

In a way I see it as an anti-spaghetti feature. Less boilerplate, shorter, more concise code with clearer intents.

My side note would be that el.querySelectorAll(selector) is versatile, but not as much as the jQuery find. Telling which cases for which browsers would not work with the native function could be some interview question, but that's not the kind of thing I'd like to remember.

It's the main reason I dislike jQuery. It's hard to debug.

    document.getElementById('non-existent').classList; // error

    $('#non-existent').addClass('yay'); // hidden bug
I prefer the explicit solution.

I don't think Array.prototype.forEach.call(el.querySelectorAll(selector)) is complex enough to pull in a new library.

It's not, but then you fall on IE9+ land, and you'll have to check if querySelectorAll returns anything first.

The sibling comment points out how a function silently failing when given empty value can be deceiptive. I guess your way of seeing it would be also in line with checking valid values before using them.

It's a very sane approach, and it requires more care and attention for each step. I'm not against it, but usually I'm not sure to see a real payoff for very conservative programming in front end DOM manipulation, I tend to prefer taking some performance hit and ignore the nitty gritty details as well as the small errors, as long as it can be recovered at a higher level.

In particular, as I looked at the IE8+ list, Many of the 3-4 line plain old js lines were 1 line in jQuery.

When writing web apps, brevity counts for a lot.

> Do not reinvent the wheel to solve problems that can't be solved in much cleaner and nicer ways. Managing dependencies can be annoying, but we all bite the bullet for a very good reason, because reusing solid well tested code is a good thing.


A thing that the examples on that site did not address is the power of jQuery("element.selector") selects a "bucket"/array of elements and functions are executed on each element in that bucket.

So now you may have to add that functionality into your library. Then there is always a non-logical browser inconsistency that needs to be taken care of. Then you need to write tests. Time used for managing the library piles up very fast.

Also, https://news.ycombinator.com/item?id=7154917

I totally agree. We need a "Why you don't need Ember" and "Why you don't need AngularJS" lesson before we even think about not needing JQuery.

We have a challenge in that so many of our web applications are built in a way that prevents us from performing analysis across technologies. For example, a modern rails app will possibly include haml, sass, coffeescript, and ruby along with the usual html, Javascript, css, etc., that are included in the various gems and plugins.

There are a lot of ways to skin this poor cat, but at this time they are generally manual and therefore unused. As a result, we try to solve dead code problems as if it is an entirely new challenge.

Dynamic code, and especially code with insufficient test coverage, poses a particular challenge, but again, it is generally possible to instrument code to see if it is ever called by the application.

Its not about reinventing the wheel. Its about being open minded. jQuery is great, and if you are going to use zepto, you might as well use jquery 2.0

But it doesnt hurt to understand how basic stuff works under the hood of jquery and to know native dom operations. The world is not black and white. Good developers know that, they dont get stuck in discussions whatever jQuery should be used everywhere or nowhere.

This response is quite strange in my eyes, because the website doesn't invent anything new, it actually says to use less bloat, which is always a good thing. Why use a well tested function if you can completely get rid of it?

And yes, less code, less abstraction, and less requirements are damn good reasons not to do something.

You're right in principle, but Zepto is a horrible recommendation because it gives the middle finger to anyone on IE < 10. I was originally designed explicitly for mobile browsers, so it makes sense, but it means it's rather unfit for the majority of businesses.

What would be awesome is if jQuery had the same kind of download builder as jQuery UI, so that you could only include the parts of it that you actually need for a library.

jQuery has support for custom builds. You can drop loads of stuff you'll probably never use if you wish!

I usually drop animations and the event shortcut functions. These seem pretty junky to me anyway.

100% agree!

did you write this post with a thesaurus? No? You literally typed EVERY SINGLE WORD in this post?

Having tools at your disposal is a good thing. Why would you type out four sentences when you can have pages of pre-written content?

Saying things more concisely in natural language is usually a good thing, too.

Only supports IE 10+ D:

Greenspun's Tenth, updated for 2014: "Any sufficiently complicated website contains an ad-hoc, informally-specified bug-ridden slow implementation of half of jQuery"

I understand the visceral opposition, but once you start writing a fallback to support some browser (something to support IE or FF or Safari or Chrome ...) you might as well use the battle-tested solution (and write your own thing if you find performance to be unacceptable and trace the bottleneck to jQuery)

The question at hand is, are fallbacks necessary anymore for the browsers we are targeting today?

And the answer to that is: generally not for IE 10 & above. Sometimes for IE9. Often for IE8.

Take a look at the caniuse tables for common functionality in JQuery:






Android 2.3 is the problem more than IE<9 for many developers at this point.

And the followup is, when do you remove fallbacks from your code? Every time I think I should remove something I end up thinking, "well, it still works just fine, does it really matter if it stays for a little longer?"

The cost is in latency and complexity for users of your head browsers. How much do you want to reduce the user experience of your users on modern browsers to support users on old ones?

There isn't a one-size-fits-all answer for this, but you should have some idea of what your traffic breakdown by browser is, and ideally what your cost in conversion rate is for each additional ms of latency (this varies by industry). I don't remember offhand what the cost per byte in latency is, but IIRC we measured something like 1ms per 1K bytes at Google (this would work out to a 1 MBps = 10Mbps connection, which seems around right for typical cable/residential fiber households these days).

I'm not sure what you mean about "complexity for users of your head browsers". The idea of the fallback/polyfill is that it doesn't even come into effect for the modern browsers.

As far as latency is concerned, I hear you and that makes sense, but the things I'm talking about are not very big, so the latency gain isn't going to matter much for our purposes.

Yeah, we definitely look at the analytics. But even if it the old browser users are sub 1 percentage point, I see the number and think, "I could take this 5 line polyfill out, but then these 1000 uniques wouldn't work."

And I just don't have the heart...

Polyfills are generally a good idea - they cost basically nothing for users of modern browsers, and they go away.

I thought that the issue in this thread is JQuery, which is a layer on top of the modern browser API (probably because the modern browser API didn't exist when it was created, and is in a large part a native implementation of JQuery functionality), and so incurs the cost of all its legacy compatibility support even if you don't need it.

Oh I see. Yeah you can just include a badge at the bottom right "Best used/viewed on Mac Firefox or Chrome".

For anyone else, just use jQuery.

  git fork jquery
  git branch "fix-performance-issue-at-<feature>"
  git commit ...
  git push

Rarely that easy. Oftentimes a performance issue can be traced back to an implementation that must support a dizzying array of use cases. You may not need all of that, but you certainly cannot just tear it out and push it back up.

You make another great point. Jquery includes tests for its implementations.

When you improve a slow implementation, it should be tested against that existing dizzying array of use cases.

I think you need a git checkout there. ;)

I assume fork aliases to clone, which gives you a checkout.

So, uh, what will I gain by ditching jQuery?

I will lose a beautiful API with a simple, terse and familiar syntax. I will have to work with an ugly, inconsistent and loquacious API, which has no guarantee of being cross-browser (or accounting for various browser quirks).

And for what? I doubt 81 KB would make much difference to 99.9% of my visitors.

As for performance -- it makes sense to rewrite bottlenecks in pure highly-optimized JS. But to write vanilla JS from scratch, without even knowing whether you'd need that performance boost is a pure waste of time.

UPD: it has been pointed out that this webpage is directed at developers of JS libraries. In this case, all these points are valid, but the title, then, seems to be either misleading (as in "link-bait" misleading) or a plain truism.

You lose dependency on a monolithic library which creates vertically-stacking dependencies and library conflicts. By ditching it, you gain the ability to construct your app out of loosely-bound components supported by independent developers.

Could you elaborate on how jQuery creates vertically-stacking dependencies and library conflicts by itself?

Obviously, you cannot have dependency conflicts if you only have a single dependency! We need a slightly more complicated example to understand the problem. Let's say I'm making the new customer checkout page for my startup.

I decide to call an e-mail address verification as a service API, their library uses jquery 1.8

I decide to call an address verification as a service API, their library uses jquery 1.11

I decide to call a credit card validation as a service API, their library uses jquery 2.0

You go to the e-mail address verification company and say "Do you have a version that supports a newer version of jquery" and they say "yes, also we redesigned our library's interface so if you upgrade you'll have to change all your code..."

You had me convinced until I scrolled down to read the code examples and realized why I actually do need jQuery. If its between adding yet another collection of utility functions to approximate the functionality jQuery would give me vs just adding jQuery. I'd rather go with jQuery.

The first example alone is reason enough to use jQuery - why would I want to use four statements instead one? Why would I want to have to remember to call `send`? Why do I have to remember the last boolean parameter of `open`?

If you are writing a library, eliminating a dependency is worth much more then 4 lines of code.

But yeah, if you are just writing code for your own site then knock yourself out.

Totally valid, but just to say, jQuery's API is just as arbitrary, you just happen to know it better. If you use the native XHR a couple times, you know what open's parameters are.

It is just as arbitrary, but I feel jQuery's API is also easier to grok at a glance. Using either a couple times may instill the parameters in your memory, but what about coming back to it after six months?

I think the question is, does your library need every function on that page? If so, just use jQuery. But do you just need one thing? Then maybe it's better to just make the one utility function rather than pull in all of jQuery.

I had exactly such a collection of DOM utility functions and was glad to give it up. For example, rooting around in element.className was never very enjoyable. Also, the site does not show handling null cases which adds more code.

You have element.classList on all modern browsers now:


It used to be that the first thing I'd reach for when building a prototype was JQuery off a CDN, but now I find that more and more of what I use JQuery for is built into the browser, and in my last few prototypes I've just stopped including it at all because I don't need it.

Except Android 2.3 and below.

Compatibility issues still exist.

Did anyone ever take you up on your hackathon idea? https://news.ycombinator.com/item?id=6645426

Nope, I didn't hear anything further on it. Still seems like an interesting event to me, though finding time might be hard. (FWIW, we do similar things within my employer all the time.)

That's too bad. But as with all things it takes time and organization in addition to some willing victims.

"Similar things" as in hackathons for fun, or hackathons structured to test out different approaches and tech?

Hackathons (really, prototypes) structured to test out different approaches.

One way of looking at it is that if you already have underscore to give you _.extend and the like, you can get pretty far with just what the browser gives you.

Which javascript library are you developing?

I would like to add a thought about the dispute about the need of using jQuery.

Let's say we know a consultant, let's call him Bob, who works on client projects. He needs to implement new features fast, and does not want to worry about low level stuff. Once he's done with a project, he moves on to another.

Then, we meet a JS-framework developer, let's call her Alice. She has to weight every line of code she writes because her decision can have have a huge impact on thousand of developers using her stuff. She needs to understand a lot of low-level details in order to make good decisions and ship rock solid stuff.

Now, both Bob and Alice have to decide whether they need to include jQuery in their projects or not. Heck, they need to justify their decisions to their teams / managers.

What's Bob going to say? He will start thinking about what will happen if he does not include jQuery to his project. Well, he will have to implement some of the low-level stuff by himself, and later maintain the code. Probably, in a month he's going to be working on another project and will have to copy & paste the same stuff over. And if there was a bug? Is he going to update all the previous projects he is not getting paid for anymore? If he's smart, he's going to say: we'll take jQuery, as it provides a nice, stable, robust and battle-hardened API. We're going to move faster if we use it, as we don't want to reinvent the wheel.

What about Alice? She will probably have to consider introducing a new dependency to her framework. Is it OK to add those additional hundreds of lines of jQuery code to an already large codebase? Is she going to be able to provide a consistent experience between different (and future) versions of jQuery? Is the core of her application going to rely on an external tool, even if it is rock-solid and lose the potential to make low-level optimizations and have full control? Maybe, she's going to say: well, I'm going to identify the elements that need some of jQuery's stuff and implement it by myself. She will be taking the time and effort needed to test it well and be sure that it works across different platforms.

At the end of the day, both will have made the right decision, even if in absolute terms they took the exact opposite action.

Software engineering is about making decisions, in a given context and moment, for a given purpose. As software engineers, we should not generalize about some of the decisions people have to make. There is no one single truth, it all depends on a variety of variables and factors. Let's be Bob and Alice, be smart and make the best decisions for our projects.

Thank you. Its astounding how much of this thread does not seem to be catching this.

My project currently depends on libraries which in turn have dependencies on mutually exclusive versions of jQuery, so we conditionally load a whole second copy some of the time. I've been meaning to fix the libraries that require older jQuery so we can fix this, but the bugs run deep, the libraries are pretty unmaintainable, and I'm under pressure to keep shipping features.

Right, and this webpage is explicitly targeting Alice.

But some of the comments on this page don't seem to get that. I'm seeing too many broad "you should never use jQuery because x" statements.

Thank you for reminding me that it's necessary to use my own judgment when deciding which approach makes the most sense to me.

I recently did a project that didn't use jQuery in order to keep my code smaller. It was an embedded 3rd-party widget, so keeping the code as small as possible was a key requirement. The code I wrote supports down to IE7, but IE7 wasn't really the biggest issue.

The real problem with not using jQuery is that all of the collective knowledge we have about browser inconsistencies is encapsulated in jQuery. When you run into this, and Google it, you'll find a million StackOverflow answers telling you to use jQuery, and if you get lucky a blog post from 2007 that actually answers your question. The result is that you end up spending time reverse-engineering jQuery to get your thing working.

To be clear, in my case the tradeoff was worth it (the code for my entire widget including the bits of library I had to write is smaller than jQuery), but it's not a tradeoff I would make unless I had a good reason.

Not sure what you're getting at. Feature support doesn't mean there aren't inconsistencies in implementation, and caniuse's documentation on that delta are very much surface-level.

Couple improvements to some of the modern-browser code examples:


  element.style.transition = 'opacity 400ms ease-in-out';
  element.style.opacity = 1;
Each & filter (this also applies to people's complaints about browser methods not working on collections):

  [].forEach.call(document.querySelectorAll(selector), function(el) { ... })
The native versions also usually run several times faster than the JQuery versions, which is the main reason to use them. This meme that you can't build performant, jank-free HTML5 mobile apps? It's largely because of JS libraries and developers that don't know which operations are fast and which are slow.

I'll also plug my colleague's autogenerated index of the HTML5 APIs:


I've had pretty terrible performance with complicated CSS animations that I managed to clear up with switching to JavaScript and requestAnimationFrame

Are you animating the transform/opacity properties and only those? That's the general secret to smooth animations on web - they're GPU accelerated, everything else requires a call into the browser's layout engine on every frame.

Transitions didn't end up being supported until IE10, which wouldn't jive with the IE8+ baseline the site proposes.

This be right on a purist level, but on every practical level there is little reason not to use [library of your choice]. If you're loading from the google/jQuery CDN (with suitable fallback, obvs.) you've got a good chance of a cache hit, and even if it misses it's a tiny one-off penalty.

And ultimately, why not? jQuery works, has a wide base of users, etc. Sure your trivial Js might not need jQuery features now, but as you add more dynamic behaviour, at some point you'll wish you had just used it to begin with.

A better message might be: make sure you know what the underlying javascript looks like, because there are a lot of people helpless without jQuery.

PLUG: if you're bored of jQuery, try Dojo. Far more power, in a less intrusive form, IMO.

i do Enterprise work & if we have jQuery in a page IBM dismisses our PMRs when we submit issues. So yeah I regularly include some simple cross-browser-normalizing js functions to use with the vendor-approved libs.

Also, jQuery is not trival to use in conjunction with other js libs (Dojo) as namespacing proponents claim. It's not like you just include both & they don't interfere. You have to follow a specific initialization pattern.

I don't understand this comment - I'm not suggesting you should use jQuery or nothing, or jQuery and Dojo. My point is the reasons given in the post for not using a DOM library of some sort are not valid.

o ok i was taking your comment within the context of the post -- more like "why not allow jQuery as a dependency for an open source lib". sorry for misread

Isn't it a giant security hole to be loading part of your library from another site you don't control?

Zillions of people do it anyway, so it's not like you won't have lots of company.

I trust Google more than most websites small enough not to have their own CDN, it's probably much easier and more likely to compromise them than Google's CDN even if of course Google is a more attractive attack surface. I guess theoretically it is, but practically I doubt it's anywhere near the most practical attack vector.

It isn't that these rebuttals are unsound, it's the sheer volume of them. A tidal wave of irritation and defensiveness always seems to accompany posts that dare question jQuery.

Unless the headline was changed by the mods, there's no hyperbole or sensationalism here. You might not need jQuery. Obviously. But many of these reactions don't belong here, they belong in a post titled You don't need jQuery, which would of course deserve to be downvoted to hell.

Obviously you don't need to pull in jQuery for every little twenty-line gizmo you publish on github. But don't you dare brag about this or you'll offend the sensibilities of those who've invested all their mental energy into learning jQuery and therefore remained ignorant of how browsers actually work.

"You might not need jQuery" -- But you have to cope with ugly syntax, browser compatibility hacks, and disconnected pieces of code. By the time you re-factor all of this, make it user friendly and lower the cognitive load, you're already re-inventing the wheel by building your own jQuery replacement, with the parts that you need.

The beauty of jQuery is working with the DOM as collections. I don't see how it's better to have all these helpers like `nextSibling`, `matches`, or `filter` thrown in the global scope or having to remember is this a real array? jQuery already built solutions for these common problems and exposes a nice API.

If all I need is querying the DOM and I don't have to support IE8 then I may consider using vanilla JavaScript, or building my own simple jQuery-esque library. But you'd start with some structure, and expose your own API. I re-invented the DOM wheel many times, and from my experience, although the code is smaller, I end up going back to jQuery because it covers some edge case or provides something else I need, like AJAX, or nice events, etc.

But building your own DOM library is a good educational challenge. Querying the DOM is all about collections, and if you don't need IE8 then you can use all the ES5 arrays methods, like map and filter. It all boils down to four functions to work with collections: toArray, unique, flatten and query. And four functions to work with the DOM: compose, join, dot, loop. See here for an example http://jsbin.com/EgIkega/1/edit. The article is more about techniques to build your own jQuery-like library; I wouldn't use "el.nextElementSibling || nextElementSibling(el)" when I can use "$(el).next()". C'mon!

Conclusion, you are probably going to use jQuery anyway.

Indeed you don't need jQuery. Though, there are standards and there are market/industry standards. jQuery has become a market standard wrapper. If jQuery isn't used, developers will still write a wrapper to ease some of these methods. It is better if that is a common market standard like jQuery than everyone doing it.

The amazing part of jQuery still to this day, beyond the selectors (which can now be replaced yes), is the plugin system. Just like Python, there is a plugin for everything and if you don't like them or there isn't one, developers can easily make one and share it with the world and it just works (tm). It is the most easily pluggable javascript library. It creates a baseplane that developers can be more efficient in. Everybody tries to replace the jQuery selectors, animation etc but they miss that jQuery is a platform and a pluggable one at that. It is responsible for tons of productivity.

"You might not need Ruby on Rails. Use C to rewrite tons of shit you need."

Use jQuery please.

Rewriting jQuery methods with vanilla js usually turns out to be a hack job that is buggy and ugly. Just use jQuery.

That's a really bad analogy.

People don't use Ruby because C's standard library works differently across different platforms.

This isn't about "rewriting jQuery methods with vanilla js". It's about using the built-in, native, vastly more performant methods that come standard on modern browsers.

The analogy is even worse because Ruby changes way faster than C :)

But anyway, writing code in any 'lower' layer is very educational.

This is exactly what we're trying to combat. For modern browsers, in many cases, it's just not true. There are a few utility methods that are tricky to replace, but you really shouldn't be including jQuery only for it's utility methods.

jQuery provides a uniform API that is guaranteed to work on supported browsers. The jQuery team does all the work to back that guarantee. If I rely on raw JS, then I'm one glitchy browser implementation away from being broken.

Even worse: suppose you build a product with the approach you recommend, it's very successful, and then your sales team makes a major sale to a stodgy old bank that still uses IE7. Or maybe you just never make the sale because you don't support the browser they use.

OK, let's say we should all turn away money from IE7 users because it's insecure and old. For OP's strategy to work, we have to assume all browsers we care about will be compatible going forward. I think this is a very unsafe assumption to make. While one small incompatibility would only be a minor annoyance, once you have more than a handful of these, a compatibility layer like jQuery again looks very nice.

And none of this even speaks to the fact that the jQuery implementation in the source article is generally at least as short and readable as the alternative, or that most people are more familiar with the jQuery version.

The only reason I can think of for dumping jQuery is maybe speed optimization, and even in that case, well-implemented jQuery should be no slower than the native speed plus the cost of a function call. If it's slow and you want to optimize something, why not optimize/bug-fix jQuery itself and help everyone, not just your one project?

I think your analogy is flawed because it seems like you're essentially taking an extreme on the opposite end from what you are sarcastically mocking.

I wouldn't call myself "old school," "hard core" or anything like it, but I just don't see what's so difficult about--or wrong with--replacing any library with "ad hoc" code that accomplishes a small subset of the library's functionality if the majority of the library's purpose is to provide that small subset. "Small", of course, is relative and context dependent.

Rewriting jQuery methods? If you can do it natively, and succinctly, why would you load a library abstraction to begin with?

You can count on one hand the number of jQuery features that most developers incorporate into their projects. E.g.:

- Setting or getting css attributes - Querying the DOM - Manipulating and walking through arrays

Each of these features can be replicated with fewer than 10 lines of code.

I don't understand why so many comments here seem to have skipped over the word "might" and the entire introduction. The point isn't stop using jQuery. The point isn't even don't ever use jQuery for plugins. It's simply that if you're only using a couple features of jQuery, consider eliminating the dependency. Why is there so much backlash to that?

It's hard to tell if this site is advocating for ditching this type of js library altogether and writing all those replacements inline (ick for some of those) or simply replacing jQuery with a thinner (and narrower) library.

I could be convinced of the latter but not the former.

One of the main things we're advocating is to consider not depending on jQuery when building an open-source project.

For Offline, PACE, Odometer, Tether, and many of our other OS projects (http://github.hubspot.com), we chose not to depend on jQuery because it means our libraries can be smaller and more people can use them.

We're happy and proud to use jQuery when building an application. As many other commenters have noticed, it can be extremely useful at reducing code complexity—and let's just say it: it can make it more enjoyable to write front-end code!

I think that what it's saying is that you can write yourself a microlibrary that just includes the ten or fifteen lines of adapter code you actually need for the thing you're building, and that you should use native browser constructs whenever possible.

> in truth, post-IE8, browsers are pretty easy to deal with on their own

I totally agree, but not everyone lives in a post-IE8 world. It's as much as 10% of our traffic on some sites and several big clients use it.

That's why it's called You_Might_NotNeedJQuery. ;)

If you are developing a library, then your users _Might_ need to support old browsers and _Might_ need jQuery.

lots of js libs are for things like webgl that already dictate a recent browser.

and I care about wether my site works on Safari or Android 2.3 browsers. Will you fix all the "wont fix" DOM bugs for me?

Would be great if we could all stop recapitulating this, it's not helping

I use jQuery because the DOM API for javascript sucks, and writing jQuery is fun.

You're average web app perhaps doesn't need the latest Ruby/Python/PHP framework, or perhaps it you can write it without the framework. Or perhaps you can a compiled as opposed to interpreted language because that would be faster. OR maybe you can use something that is even faster, like perhaps Assembler! Fuck it write machine code if speed is the most important thing.

Do you know why you don't? Cause writing Assembler or machine code sucks. You lose very little in load time by including a minified version of jQuery, while you gain an enormous amount of ease of use and readability. Also it'll be more fun.

Just include the jQuery and be done with it.

I use jQuery because the DOM API for javascript sucks, and writing jQuery is fun.

How many lines of code are actually needed to give you selectors and the most common DOM manipulations?

How many lines of code are in jQuery?

Is there anything which would not be in selectors + common manipulations that you need, and which only jQuery can provide?

DOM selectors and events are critical, maybe ajax. Perhaps you could pare it down a bit - I don't need the animation stuff. I have no idea what the size using only what I might need when I needed it.

But then that becomes a whole another endeavor - how much load time will be saved by only using the parts you need, and how long will it take to figure out what you need and what you dont? It's all about return on investment. What do I need now, what won't I ever use, and what might I use later. It becomes more work to save, what, 1/4 second? Maybe a bit more on mobile. It isn't worth the trouble.

The whole obsession over the load time of jquery feels like an exercise in OCD.

It's odd, but after reading everything and the examples at the end, I feel we need jQuery more than ever. Kind the opposite of the OP is stating. Great post though.

great content, terrible opinion. I like your take on the article.

You might need some semi-colons though...


My colleagues and I learnt that lesson the hard way. We are working on a WYSIWYG editor (Aloha-Editor) and the first version did depend on jQuery (and jQuery UI for that matter). That caused a lot of trouble for people integrating the editor in their websites, especially if they were already using jQuery. For our particular case we really didn't need it, as it's just as easy to say .getAttribute() instead of .attr(), and we didn't use selectors much, if at all. Effort is underway to get rid of the dependency from the core library in the next major release.

Makes me think of: http://vanilla-js.com/

You know that is a joke right?

This is fascinating to me since I'm already moving away from jQuery. I'm always looking for other ways to do what many people use jQuery for. For example, I'm now using CSS3 animations and transitions instead of jQuery.

I've also started using Angular.js quite a bit and have found most of the time, it requires less code than jQuery. It also has its own subset of jQuery "jqLite" which has a much smaller footprint so your app doesn't need to rely on that jQuery dependency.

You might not need jQuery 1.x.

You might be able to use jQuery 2.x instead, which is smaller, faster, and drops support for IE8 and below.

querySelector and querySelectorAll have bugs in IE8. Checkout the jQuery source code and search for these functions and see the comments and workarounds if you want to be sure:


Notice the rbuggyQSA variable.

Also check out Quirksmode:


I don't know if i need jQuery or not But your page is seriously a great "Cheat Sheet" for all jQuery Learners out there ! Thanks

My favorite part is how I learned that I don't need to use `var`—I can make everything global!!

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