Created by Maximilian Schwarzmüller
    Last Updated on April 23, 2018

    # Why do we even discuss the future of jQuery?

    Don’t miss the video above the article!

    Because jQuery still runs the majority of the frontend web logic! It powers around 70% of the top web pages and 20% of the entire web (Source). That’s huge!

    But this makes the question regarding its future even stranger.

    jQuery has problems. It’s everywhere and it’s not really future-proof. It was an amazing tool when it was released back in 2006 but the core issues it fixed back at the time aren’t issues anymore. Instead, you now can run into way more problems when using jQuery.

    To understand this, let’s consider the issues jQuery fixed back in 2006.

    1. JavaScript was kind of broken and browsers implemented it very differently

    This was one of the major things jQuery helped with. All of a sudden, you had an easy-to-use API which allowed you to manipulate the DOM. And even better than that: The same API worked across all major browsers!

    $('h1').text('Awesome!')

    2. JavaScript and the web as whole were way less mature

    jQuery allowed developers to simply “do more” on the web - on the frontend to be precise. Creating engaging user interfaces (for which you need JavaScript) was easier because you could use a well-documented API. Animating elements, adding and removing content, changing styles and re-ordering items was significantly easier to achieve than with vanilla JavaScript. jQuery also added a powerful and yet accessible Ajax API which made the sending of background requests easy as well. This is a core building block of JavaScript-driven UIs since you don’t have to load a new page upon every user action and can load or manipulate server-side data behind the scenes.

    # What has changed?

    The issues fixed by jQuery aren’t issues anymore.

    JavaScript matured, browser compatibility got way better. We got a vibrant frontend development ecosystem with thousands of packages and tools, we can use way more powerful Ajax libraries like Axios if we want to.

    This does not mean that everything’s great but the core problems that were fixed by jQuery don’t really exist anymore.

    Instead, jQuery now is a tool which is often (not always of course) used by less experienced web developers who never made the switch to vanilla JavaScript or frameworks like Angular or React.

    And that’s important to understand by the way: We’re not just talking about jQuery vs Angular. Vanilla JavaScript is a real alternative!

    Whilst DOM traversal and manipulation was way more difficult in 2006, we got many functionalities like querySelector built into vanilla JavaScript now. These things work and they even work across browsers.

    // jQuery
    $('h1').text('Is this really that much better and worth the extra dependency?')
    
    // Vanilla Javascript
    document.querySelector('h1').textContent =
      'Or is this pretty much equally good?'

    If you have the possibility of using vanilla JavaScript instead of achieving basically the same with jQuery, it’s obviously better to use the vanilla option. You save the extra package download and you don’t have to learn an extra syntax.

    # It’s not just Vanilla JavaScript…

    It’s not just vanilla JavaScript though. We simply got better alternatives these days.

    Vanilla JavaScript clearly still has its limits. If you’re building a complex UI with a lot of logic implemented via JavaScript, you quickly end up in situations where you essentially have to write some kind of spaghetti code. Managing DOM state is difficult after all.

    And not just that. You regularly run into situations where your DOM traversal logic breaks if you ever decide to re-order your HTML code (or introduce new elements).

    <div id="news">
      <h1>What's new?</h1>
      <div>
        <p>An interesting discussion over the future of jQuery evolved over the last days.</p>
      </div>
    </div>
    $('#news')
      .find('div')
      .find('p')
      .text('This replaces the paragraph text - hopefully')

    This code will stop working if you change the HTML code like this.

    <div id="news">
      <h1>What's new?</h1>
      <p>An interesting discussion over the future of jQuery evolved over the last days.</p>
    </div>

    And the same would be true for vanilla JavaScript traversal techniques.

    Obviously, you can write code that would still work in the above scenario. But it might then break under different circumstances. Or you end up with quite a long chain of traversal methods to safely select whatever you plan on manipulating. And this only becomes more difficult if you manually create or remove DOM elements via jQuery.

    If you ever had a use-case where you needed to add and remove elements dynamically - let’s say based on some JavaScript array holding data - you know the pain that is associated with that when using jQuery or vanilla JavaScript. Leave alone if you then want to work with these elements (e.g. attach click listeners or styles).

    var loopData = ['Apples', 'Bananas', 'Milk']
    
    $.each(loopData, function(index, value) {
      $('<div>' + value + '</div>')
        .click(function() {
          $(this).toggleClass('highlighted')
        })
        .appendTo($('#loop'))
    })

    # Frameworks to the rescue!

    There’s a fix for that!

    JavaScript frameworks like Angular, React (oh, that’s a library actually - forgive me React folks) or Vue for example.

    All these frameworks have one fundamental difference compared to jQuery (and vanilla JavaScript): You don’t write code to manually navigate the DOM.

    You use a declarative approach instead.

    What does this mean?

    Well, here’s how you could safely select and manipulate the HTML content from earlier in this article - this time using Vue:

    <div id="news">
      <h1>What's new?</h1>
      <div>
        <p>{{ myText }}</p>
      </div>
    </div>
    new Vue({
      el: '#news',
      data: {
        myText: 'This never fails to hit its target',
      },
    })

    As you can see, Vue clearly follows a different philosophy than jQuery does. The same would be true for React and Angular by the way.

    For the rest of this article, I’ll use Vue for the examples - simply because it has a very nice syntax and it’s easy to get started with. Import Vue into your web page and you’re good to go.

    But Angular and React also follow comparable approaches. If you want to learn more about these, I got helpful resources for you:

    And of course, in case you want to dive deeper into Vue, I got resources on that too: Vue - The Complete Guide.

    They all focus on allowing you to simply mark places in the DOM where content should be displayed. You don’t have to describe the path to that place - the framework will figure it for you!

    # But the Vue solution is longer!

    If you compare the jQuery solution to the Vue solution, you clearly see that the Vue approach is a bit longer (in terms of code lines written).

    But this was a very simple example! More complex examples quickly grow in size and, even worse, complexity when it comes to jQuery code required. But not for Vue (or the other frameworks).

    That is because the general approach is so different. If you just describe your data structure, your logic and how you connect your data to the DOM (your template so to say), you don’t have to write that much additional code when your HTML code or business logic becomes more complex.

    For jQuery, that’s a different thing though. If you need to reach elements which are deeply nested or if you need to do complex things like looping through to-be-created elements, you quickly end up with the more complex (and also error-prone) code you saw earlier.

    var shoppingList = ['Apples', 'Bananas', 'Milk']
    
    $.each(shoppingList, function(index, value) {
      $('<div>' + value + '</div>')
        .click(function() {
          $(this).toggleClass('highlighted')
        })
        .appendTo($('#loop'))
    })

    This will yield:

    <div id="output">
      <div>Apples</div>
      <div>Bananas</div>
      <div>Milk</div>
    </div>

    The nested <div> elements are clickable and the highlighted CSS class will be added to any element upon clicking.

    Consider the Vue (and HTML) snippet which would achieve the same:

    new Vue({
      el: '#output',
      data: {
        shoppingList: [
          { name: 'Apples', selected: false },
          { name: 'Bananas', selected: false },
          { name: 'Milk', selected: false },
        ],
      },
    })
    <div id="output">
      <div
        v-for="item in shoppingList"
        v-on:click="item.selected= !item.selected"
        v-bind:class="{highlighted: item.selected}">{{ item.name }}</div>
    </div>

    It’s still some line of codes you need here but it’s so much easier to understand, maintain and edit! You declare what your HTML code should look like in the end, you describe your data and manage your selected state in your JS code.

    The magic happens with the help of so-called directives - v-for (for looping), v-on (for event listening) and v-bind (for changing the HTML element) are doing all the work here. React and Angular generally got comparable solutions, though React doesn’t use directives. It still won’t force you to manually write all the code for selecting and creating elements.

    As your (frontend) web app grows and you build even more complex UIs, you’ll love such a declarative approach which doesn’t force you into endless, unmaintainable chains of css(), $(...) and appendTo() calls.

    # Is jQuery smaller at least?

    Vue offers a distinctly different syntax - it does a lot of the heavy lifting regarding DOM access and manipulation for you.

    That clearly has to come at a price, doesn’t it? jQuery certainly is smaller, right?

    Well … no. That’s not the case.

    As of March 2018 jQuery weighs 29kb minified and gzipped whereas Vue comes at 30kb minified and gzipped. Vue and jQuery both come at roughly 30kb minified and gzipped. What about React and Angular?

    React actually consists of two packages: ReactDOM and React itself. Combined, you have to download roughly 34kb minified + gzipped to get it up and running.

    Angular is way bigger than that since Angular is a way bigger framework which is especially suited for big enterprise applications. For such types of apps, it’ll win against jQuery not because of it’s package size but because of all the pain it saves you.

    # So…never use jQuery again?

    The question now of course is whether you should always use Vue, Angular or React then. Or are there use-cases where using jQuery still makes sense?

    In general, I believe that jQuery’s time is coming to an end. At least in its current form.

    You could still pick it for trivial cases but why wouldn’t you just use vanilla JavaScript for that and save the extra 30kbs + the extra syntax you have to get into? You’ll be a better web developer if you know vanilla JS anyways.

    jQuery obviously still sees a lot of use in many legacy web apps and it’s going to stay there for quite some time.

    If you need to work on such web apps, you probably won’t find a way around jQuery for now and learning it might hence still be something worth your time.

    A lot of popular third-party packages also still rely on jQuery - Bootstrap, the CSS framework, does so for example (unfortunately it even does so in its latest version - 4.x). Having to add the extra dependency because of such a package is annoying, hence I personally always try to find out what exactly jQuery does for that given package. Once you got that piece of information, you can rebuild the functionality with vanilla JS or some other framework and successfully get rid of jQuery thereafter.