You may not need jQuery

Table of contents

Vanilla JS has come a long way since the days of ES5, adding features like string templates with interpolation, promises and module imports. Modern javascript is not quite as unwieldy as the language once was at the time jQuery came into existence. That doesn't mean jQuery has no place in the current ecosystem - but it does create a case against importing jQuery into all of your projects by default.

The case against jQuery

On the web, loading times are extremely important. A major contributor to longer load times is javascript, as it needs to first be downloaded and then be executed. Javascript libraries often only boast their download size as "gzipped" - which has some drawbacks:

  • GZIP has multiple compression levels. While sizes are usually given from level 9, this is not economical for web servers as it adds significant CPU usage to every request. Web servers will typically opt for compression levels from 3-6 for a better cost tradeoff, creating a slightly larger file to be downloaded in production than claimed by the library's marketing.
  • Compression only helps during the downloading step, not the execution. Even if your 116kb javascript library compresses down to 68kb, your browser still needs to execute 116kb of javascript - Before the first line of your page code even runs, that is.

While on the surface your own code will be slightly shorter using jQuery, adding the library often adds much more weight to your application that you save in your own code by using it.Every feature jQuery contains is downloaded and executed - even if you don't use it. And chances are, you aren't using even half of jQuery's functions.

jQuery to vanilla js cheat sheet

If you haven't touched vanilla javascript in a while, you will probably remember how annoying some functionality like triggering a click on an element or toggling html classes were in ES5. If that's you, then you are in luck - it got a whole lot easier:

// jQuery and vanilla javascript equivalents


$(document).ready(function(){...
document.readyState !== "loading" ? main() : document.addEventListener("DOMContentLoaded", main); function main{ ...


$("span").find("a")
document.querySelectorAll("span a")


$("span").each(function(el){...
for(const el of document.querySelectorAll("span")){...


$("span").text("hello")
document.querySelector("span").innerText = "hello"


let name = $("input").val()
let name = document.querySelector("input").value


$("form").submit()
document.querySelector("form").submit()


$("button").click()
document.querySelector("button").click()


$("div").hide()
document.querySelector("div").style.display = "none"


$("a").css({"text-decoration": "underline"})
document.querySelector("a").style.textDecoration = "underline"


$("button").toggleClass("active")
document.querySelector("button").classList.toggle("active")


$(".menu").hasClass("active")
document.querySelector(".menu").classList.contains("active")


$(".terms").on("click", function(e){...
document.querySelector(".terms").addEventListener("click", (e)=>{...


$(".box").append("<div></div>")
document.querySelector(".box").appendChild(document.createElement("div"))


$(".box").prepend("<div></div>")
document.querySelector(".box").insertBefore(document.createElement("div"), document.querySelector(".box").firstChild)

But jQuery makes you more productive

While lots of features were added to javascript over time, some things are still a lot easier to do in jQuery than vanilla js. One such case are functions allowing the creation of html elements from raw strings, like the html(), append() and prepend() functions jQuery provides, which to this day have no direct competitor in vanilla js:

// helper function for vanilla js
function htmlToElement(html) {
    let template = document.createElement('template')
    template.innerHTML = html.trim()
    return template.content.firstChild
}

// jQuery
$(".box").prepend("<div>Hello world!</div>")
// javascript
document.querySelector(".box").appendChild(htmlToElement("<div>Hello world!</div>"))

// jQuery
$(".box").append("<div>Hello world!</div>")
// javascript
document.querySelector(".box").insertBefore(htmlToElement("<div>Hello world!</div>"), document.querySelector(".box").firstChild)

// jQuery
$(".box").html("<div>Hello world!</div>")
// javascript
document.querySelector(".box").innerHtml = htmlToElement("<div>Hello world!</div>")

In addition to the few features still missing easy alternatives in javascript, jQuery also added workaround for several browser bugs over the years, which can be found in the source code by searching for comments starting with // Support:.



So, should you ditch jQuery? The answer is: maybe. If you value productivity and speed during development, jQuery is still hard to beat. Code written using it tends to be easier to read and and the included workarounds for bugs in specific browser versions enable faster prototyping and lead to less debugging.

But adding a library like jQuery adds significant cost in terms of bandwidth and cpu usage to your app, decreasing load times and making the page less responsive on less resource-rich devices like mobiles. Writing vanilla javascript will always outperform the use of libraries like jQuery once the app is deployed in production, especially if you only needed it for syntactic sugar and not as a dependency of other libraries. It is up to you to decide which is more important to you and what tradeoffs you are willing to take.

More articles

Avoiding pitfalls with the net/http package in go

Prevent nasty surprises when building http server apps in go

Concurrent worker pools in go

Distributing work among a fixed number of goroutines

Pointers 101: The Good, the Bad and the Ugly

Make the most of pointers without worrying about their pitfalls anymore

The downsides of source-available software licenses

And how it differs from real open-source licenses

Configure linux debian to boot into a fullscreen application

Running kiosk-mode applications with confidence

How to use ansible with vagrant environments

Painlessly connect vagrant infrastructure and ansible playbooks