npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

jx-query

v1.0.3

Published

A minimal jQuery-like library for DOM manipulation

Downloads

9

Readme

jxQuery

Bundlephobia Bundlephobia Bundlephobia

Yet another tiny jQuery-alike. If that's the case, why bother?

  • It makes use of proxies, exposing the underlying elements when you just want vanilla JS.
  • It hopefully provides a nice balance between ergonomics and usefulness for its size.
  • It provides an easy way to add your own functionality.

Show me what you've got then

Its core functions are what you'd expect, $() and $$() for single elements and lists respectively.

$() can accept either a CSS selector or an Element and will return a proxied Element or null.

const el = $('div.container')
const el2 = $(el) // this will pass back the proxied el and won't make a proxy of a proxy

const el3 = document.querySelector('body') // non-proxied element
const el4 = $(el3) // this will create a new proxy

$$() accepts a CSS selector and will return an Array (rather than a NodeList) of proxy-wrapped Elements.

Function calls are chainable outside of terminating functions like getAttribute or map.

$$() functions will apply to all of the Elements of the Array following the same return rules as $().

const els = $$('a')

// set listener on all anchor elements, wrap e.target with $() and use base Array's map method
// map returns values so it's a terminating call (cannot chain)
els
  .css('background-color: red')
  .on('pointerover', (e) => console.log($(e.target).attribute('href')))
  .map((e) => e.attribute('href'))

Functions

attribute()
type attribute = (
  attr: string | object,
  value?: any
) => string | null | undefined

const el = $('div') // returns Element or null

el.attribute('name') // get the value of the passed attribute, null if not found
el.attribute('name', 'jxQuery') // set attribute
el.attribute('name', null) // passing null specifically will remove the attribute

// it also accept objects for set/null
el.attribute({
  name: 'href',
  target: null
})

const els = $$('a') // returns Element[]

els.attribute('href') // returns an array of hrefs from all anchor elements
css()
type css = (styles: string | object) => void

const els = $$('div') // returns Element[]

els.css({ borderWidth: 'medium', 'border-color': 'red' }) // object accepts kebab and camelCase
els.css('background: red; opacity: .5') // strings are destructive, overwriting the entire style attribute
on()
// el.addEventListener
type on = (
  type: string,
  listener: EventListenerOrEventListenerObject,
  options?: boolean | AddEventListenerOptions
) => ProxyHandler<Element | Element[]>

const el = $('div')

el.on('click', (e) => console.log(e.target)).on('pointerover', (e) =>
  console.log('hovering over', e.target)
)
off()
// el.removeEventListener
type off = (
  type: string,
  listener: EventListenerOrEventListenerObject,
  options?: boolean | EventListenerOptions
) => ProxyHandler<Element | Element[]>

const el = $('div')
const fn = (e) => console.log(e)

el.on('click', fn).css('background-color:pink').off('click', fn)
addClass()
// el.classList.add
type addClass = (...tokens: string[]) => ProxyHandler<Element | Element[]>

$('main').addClass('boop', 'doop', 'swoop').attribute('class') // 'boop doop swoop'
removeClass()
// el.classList.remove
type removeClass = (...tokens: string[]) => ProxyHandler<Element | Element[]>

$('button').removeClass('btn-primary').addClass('btn-info')
toggleClass()
// el.classList.toggle with void override for chaining
type toggleClass = (
  token: string,
  force?: boolean
) => ProxyHandler<Element | Element[]>

$('div#chart').toggleClass('hide', true) //force true acts like add, false like remove
replaceClass()
// el.classList.replace with void override for chaining
type replaceClass = (
  oldToken: string,
  newToken: string
) => ProxyHandler<Element | Element[]>

$$('button').replaceClass('btn-primary', 'btn-info')
trigger()
// el.dispatchEvent(new Event(type: string, eventInitDict?: EventInit) => Event) with void override
type trigger = (
  type: string,
  eventInitDict?: EventInit
) => ProxyHandler<Element | Element[]>

$('button').trigger('click')
remove()
// el.parentNode.removeChild
type remove = () => ProxyHandler<Element | Element[]>

$('div').remove() // this ONLY removes the dom element, the js reference still exists

Convenience Functions on $

$.makeGlobal()

Exactly what's written on the tin, binds $ and $$ to the global scope.

$.makeGlobal()
$.ready()
// run callback function when dom is loaded
$.ready(() => console.log('DOM is ready!'))
$.addHandler()

Any function here will be added to the proxy's get function as prop: (target, args) => any. A return value other than undefined or null will be terminating.

// add enable/disable functions
$.addHandler('enable', (target) => (target.disabled = false))
$.addHandler('disable', (target) => (target.disabled = true))

Inspired to various degrees by projects like jQuery, htmx, surreal.js, this DomQuery gist, and Alpine.js.

All of this can be done in fairly painless vanilla.js, but if you like the ergonomics of this tiny library, any of the vanilla.js solutions can be ported in as handlers.