jQuery to Vanilla JS

jQuery-to-Vanilla-JS Equivalents

Every jQuery 561 idiom has a native counterpart. When porting, remember that querySelectorAll() returns a static NodeList whose methods do not apply to every element (loop with forEach), and querySelector() returns null rather than an empty set, so guard with optional chaining: el?.remove().

jQuery idioms and their native replacements
jQuery Vanilla JavaScript
$('.a'), $el.find('.a') document.querySelectorAll('.a'), el.querySelectorAll('.a')
$el.closest('li'), $el.parent() el.closest('li'), el.parentElement
$el.next(), $el.is('.on') el.nextElementSibling, el.matches('.on')
$el.each(fn) list.forEach(fn)
$el.append(html) el.insertAdjacentHTML('beforeend', html)
.before(), .after(), .remove() Same names on Element (Adding and Removing Nodes)
$el.empty(), $el.clone() el.replaceChildren(), el.cloneNode(true)
$el.text(), $el.html(), $el.val() el.textContent, el.innerHTML, el.value
$el.attr(n, v), $el.data('k') el.setAttribute(n, v), el.dataset.k
$el.addClass('a'), .toggleClass('a') el.classList.add('a'), .toggle('a')
$el.css('color', 'red'), .css('color') el.style.color = 'red', getComputedStyle(el).color
$el.outerWidth(), $el.offset() el.offsetWidth, el.getBoundingClientRect()
$el.hide(), $el.fadeIn(400) el.hidden = true, el.animate([{ opacity: 0 }, { opacity: 1 }], 400)
$el.on('click', fn), .one('click', fn) el.addEventListener('click', fn), plus { once: true }
$ul.on('click', 'li', fn) Listener on ul checking e.target.closest('li')
$el.trigger('saved', data) el.dispatchEvent(new CustomEvent('saved', { detail, bubbles: true }))
$(fn) <script defer> or DOMContentLoaded
$.getJSON(url) fetch(url).then((r) => r.json()) (AJAX with Fetch)
$form.serialize(), $.param(obj) new URLSearchParams(new FormData(form)), new URLSearchParams(obj)
$.Deferred(), $.when(a, b) Promise.withResolvers(), Promise.all([a, b])
$.extend(true, {}, obj) structuredClone(obj)