A lightweight modular jQuery clone/alternative library built for modern browsers in ES6 with full TypeScript support.
This project is in beta, make sure to test your integration with this code thoroughly before deploying
jQuery is a great library, the API is simple yet expressive, but with advancements in browser technology often the full functionality of jQuery is not needed, and there is not really a granular way to remove the bits you aren't using.
Wouldn't it be good to have a simpler jQuery like library that is modular?
Dabby.js is a jQuery alternative designed to be as simple and streamlined as possible whilst covering as much of the jQuery API as much as is feasibly possible in a small size (<10kb minified and Gzipped), you can also build it as part of your project and only include the bits you are actually using.
Find out more about the project here.
- Modular — import only the methods you need, tree-shake the rest
- TypeScript-first — written in TypeScript with automatic type inference via module augmentation
- Trusted Types — compatible with
require-trusted-types-forCSP directive - jQuery 4 parity — CSS px allowlist,
.even()/.odd(), FormData support, DOMParser-based HTML parsing - Small — <10kb gzipped for the full bundle
Want to get started quickly? Download the latest release here.
Want to build the bundle yourself? Make sure the following software is installed:
- Git
- NodeJS
Clone the repository, and build it:
$ git clone https://github.com/hexydec/dabby
$ cd dabby
$ npm install
$ npm run build
Then swap jQuery out for Dabby.js in your project.
Next you should probably audit and refactor your code to update anything that Dabby.js will definitely not support, like custom pseudo selectors or any animation methods.
Then run it in the browser, or through your test suite to highlight any other issues.
Dabby.js compiles an ES6 module with TypeScript definitions. Include Dabby.js like this:
import $ from "dabbyjs"; // or "dabbyjs/full" for the complete bundleFor TypeScript projects:
import $ from "dabbyjs"; // Automatically includes type definitionsBrowser support for Dabby.js can be found here:
Dabby.js is billed as a jQuery clone library, and as such tries to implement as much of the jQuery API as is feasible without getting away from being fast, small, and letting the browser do most of the work.
Every module has its own readme with signatures, parameters and examples. Click any method below to jump to its docs.
The $() factory and the underlying Dabby class. Methods on this section are always available — no extra import needed.
$()factory andDabbyclass — selectors, HTML creation, ready callback$.fn.each()— iterate the collection$.fn.get()— get a node from the collection$.fn.map()— translate the collection through a callback
$.fn.html()— get/set inner HTML$.fn.text()— get/set text content$.fn.append()/.prepend()/.before()/.after()— insert content$.fn.appendTo()/.prependTo()/.insertBefore()/.insertAfter()— insert into a target$.fn.empty()— remove children$.fn.remove()/.detach()— remove from DOM$.fn.replaceWith()/.replaceAll()— swap nodes$.fn.clone()— deep-copy elements$.fn.wrap()— wrap each element$.fn.wrapAll()— wrap a group$.fn.unwrap()— remove the parent
$.fn.attr()— get/set HTML attributes$.fn.prop()— get/set DOM properties$.fn.removeProp()— delete a property$.fn.data()— read/writedata-*$.fn.val()— get/set form values$.fn.css()— get/set inline CSS$.fn.addClass()/.removeClass()/.toggleClass()— class manipulation$.fn.hasClass()— class predicate$.fn.show()/.hide()/.toggle()— visibility
$.fn.on()/.one()— bind handlers (with optional delegation)$.fn.off()— remove handlers$.fn.trigger()— fire an event$.fn.triggerHandler()— invoke handlers without dispatching- Named events:
click,keydown,submit, … — 24 jQuery-style shortcuts
$.fn.find()— descendants matching a selector$.fn.children()— direct children$.fn.parent()/.parents()/.parentsUntil()— ancestors$.fn.closest()— nearest matching ancestor$.fn.siblings()— siblings$.fn.next()/.nextAll()/.nextUntil()/.prev()/.prevAll()/.prevUntil()— sibling chain$.fn.filter()/.is()/.not()— narrow or test a collection$.fn.has()— keep parents containing a match$.fn.add()— combine collections$.fn.first()/.last()/.eq()— pick by position$.fn.even()/.odd()— even/odd index subsets$.fn.slice()— array-style subset$.fn.index()— position lookup
$.fn.width()/.height()/.innerWidth()/.innerHeight()/.outerWidth()/.outerHeight()— measurements$.fn.scrollLeft()/.scrollTop()— scroll position$.fn.offset()— viewport position$.fn.offsetParent()— nearest positioned ancestor$.fn.position()— position relative to the offset parent
$.ajax()— primary request method$.get()/$.post()— GET/POST shortcuts$.getScript()— load and execute a script$.fn.load()— load HTML into elements$.fn.serialize()— serialise a form$.param()— serialise an object as a query string
$.each()— iterate any collection$.map()— translate any collection$.extend()— shallow/deep merge$.parseHTML()— parse HTML to nodes$.isPlainObject()— plain-object predicate$.isArray()— array predicate (Array.isArraywrapper)$.isFunction()— callable predicate$.isWindow()— window predicate
As Dabby.js is built in ES6, you can include just the parts you need in your project (if you are using ES6 modules). Import the core library and only the methods you need:
import $ from "dabbyjs";
import "dabbyjs/attributes/attr/attr"; // create elements with attributes like $("<element>", {some: "attributes"})
import "dabbyjs/traversal/filter/filter"; // $.fn.is(), $.fn.filter() and $.fn.not()You can either do this in each module you need dabby.js in, or build a file that imports all the methods you need for your project, and include that somewhere.
Dabby.js is written in TypeScript with a seamless developer experience. Import $ and the modules you need — all types are automatically added via module augmentation. No separate type imports required.
import $ from 'dabbyjs/full';
// All methods available with full type safety and IntelliSense
$('#app').html('<div>Hello</div>').addClass('active').on('click', () => {});
const text = $('#app').text(); // inferred as stringImport only the modules you need. TypeScript automatically knows which methods are available based on your imports:
import $ from 'dabbyjs';
import 'dabbyjs/manipulation/html/html';
import 'dabbyjs/events/on/on';
// TypeScript knows html() and on() are available, with perfect autocomplete
$('#app').html('Hello').on('click', () => {});
// TypeScript error — css() was not imported
$('#app').css('color', 'red'); // Error: Property 'css' does not existMethod chaining preserves all augmented types — every chained call returns the full type with all imported methods available.
Dabby.js supports the Trusted Types API for environments with Content-Security-Policy: require-trusted-types-for 'script'. All HTML-accepting methods (.html(), .append(), .prepend(), .before(), .after(), $()) accept TrustedHTML objects and route string assignments through a trustedTypes policy.
// TrustedHTML objects pass through directly
const policy = trustedTypes.createPolicy('myApp', { createHTML: (s) => DOMPurify.sanitize(s) });
$('#app').html(policy.createHTML('<div>Safe HTML</div>'));
// Raw strings are wrapped via dabby's own policy automatically
$('#app').html('<div>Hello</div>'); // Works in both enforced and non-enforced environmentsnpm run build # TypeScript compilation + Vite bundle
npm run build:types # TypeScript declarations only
npm run build:bundle # Vite bundle only
npm run dev # Watch mode
npm run test:types # Run type tests (tsd)You can always swap dabby.js out for jQuery to see if the issue is with your code or dabby.js. It is a very young library which hasn't been tested as much as jQuery, so expect bugs. But this library is being used in production of most of my own websites.
If the issue still persists, you can create an issue for it in the tracker.
If you find an issue with dabby.js, please create an issue in the tracker, fork the code, fix the issue, then create a pull request, and I will evaluate your submission.
Also look at the To Do list and the coding style guide.
The MIT License (MIT). Please see License File for more information.