Remove jQuery and other legacy libraries

jQuery and similar libraries still load on many pages. What they cost, how to find out whether you need them, and how to replace them with browser features.

IntermediateHow-to5 min readUpdated October 30, 2026

In this guide
  1. What the library costs
  2. Find out whether you use it
  3. Native replacements
  4. A safe plan
  5. Other legacy code to look for
  6. What not to do
  7. Check your own page
  8. Sources

What the library costs

These sizes are measured from the files in the packages published on npm, which we downloaded on 30 October 2026. "Unpacked" is the minified file as the browser sees it after decompression. The compressed sizes were made with gzip at its highest level and Brotli at quality 11, so a real server that compresses less aggressively sends a little more.

FileUnpackedgzipBrotli
jQuery 4.0.078.7 KB27.5 KB25.0 KB
jQuery 4.0.0, slim build56.0 KB19.5 KB17.7 KB
jQuery 3.7.187.5 KB30.3 KB27.4 KB
jQuery 3.7.1, slim build70.3 KB24.1 KB21.8 KB
jQuery Migrate 3.6.019.4 KB6.5 KB5.9 KB

The download is the smaller part of the cost. The browser also parses, compiles and runs the file. Where it is loaded matters too: a copy in the head without defer blocks the page. See defer, async and modules.

Keep this in proportion. In the 2025 Web Almanac the median mobile home page loaded 632 KB of JavaScript, so jQuery on its own is a few percent of a typical page. The reason to look at it is what comes with it: the plugins that depend on it, the code you have written on top of it, and the old habits it represents. On a page that is struggling with Total Blocking Time, the whole stack counts.

Find out whether you use it

Native replacements

For simple uses, the browser already has an equivalent. This table is a starting point, not a complete list.

In jQueryIn the browser
$('.item')document.querySelectorAll('.item')
$('#menu')document.getElementById('menu') or document.querySelector('#menu')
$(el).addClass('open')el.classList.add('open')
$(el).on('click', fn)el.addEventListener('click', fn)
$(el).closest('.card')el.closest('.card')
$(el).data('id')el.dataset.id
$.each(items, fn)items.forEach(fn)
$.get(url) or $.ajax(...)fetch(url)
$(el).animate(...)A CSS transition or animation, or el.animate(...)
$(document).ready(fn)A script with defer, or the DOMContentLoaded event

For example, a small menu script with jQuery:

$('.menu-button').on('click', function () {
  $('.menu').toggleClass('open');
  $.get('/api/menu-state', function (data) { console.log(data); });
});

and the same without it:

document.querySelector('.menu-button').addEventListener('click', () => {
  document.querySelector('.menu').classList.toggle('open');
  fetch('/api/menu-state').then((r) => r.json()).then(console.log);
});

Browser support is not a concern for these. Element.closest() works since Chrome 41, Firefox 35 and Safari 6. classList has worked in Chrome since version 22, Firefox since 3.6 and Safari since 7. fetch() works since Chrome 42, Edge 14, Firefox 39 and Safari 10.1, and Element.animate() since Chrome 36, Firefox 48 and Safari 13.1.

A safe plan

  1. List the uses. Search your code and the page for $( and jQuery. Make a list of what it does, and which plugin each use comes from.
  2. Remove what nobody needs. Plugins and widgets that no longer matter are the cheapest savings.
  3. Try the slim build. The jQuery README says it releases a slim version that excludes the ajax, callbacks, deferred, effects and queue modules. If your code uses none of them, the file shrinks by about a fifth to a little over a quarter of its unpacked size, as the table shows.
  4. Replace your own code first, then the plugins. Rewrite small scripts with native code, one at a time, on a test copy, and test each one. For third-party plugins, look for a version or an alternative that does not need jQuery. If you cannot replace a plugin, keep jQuery and load it only on the pages where the plugin runs.
  5. Load what is left late. Add defer, and do not load it where it is not needed.
  6. Measure. Compare Total Blocking Time and the main-thread work before and after. See where main-thread time goes.

On WordPress, take extra care. The bundled jQuery Migrate exists to keep older code working, so removing it can break plugins that still rely on old behavior, and swapping the bundled jQuery for another version can do the same. Test every page type, including the checkout and the forms, before you change either.

Other legacy code to look for

What not to do

Check your own page

Run the free audit and look at the list of JavaScript files and Reduce unused JavaScript. If jQuery and several plugins are among the largest files, work through the plan above. If the audit shows only a small amount of script, spend your time on something else.

Sources

Start here

Free website audit

Live Google data for any public page: mobile and desktop.

Mobile + desktop · Lighthouse lab test · Real-user Chrome data when Google has it

Rather have this done for you? Speed optimization · Book a call

Related guides

All guides →