A jQuery plugin that adds reactive state and declarative DOM binding — without a build step, a virtual DOM, or a component model.
Most jQuery projects hit the same wall: a piece of UI depends on more than a couple of values, and keeping the DOM manually in sync starts getting messy fast. You end up with code like this:
// Vanilla jQuery — imperative, brittle
$('#inc').on('click', function() {
count++;
$('.counter-display').text(count);
$('.step-tracker').text(`Step ${count} of 10`);
if (count >= 10) $('.done-msg').show();
updateProgressBar(count);
});
Every time count changes you have to remember every element that depends on it. Add a
new display element and you're back editing every event handler. Miss one and you have a
stale-display bug.
reQuery inverts that relationship. State is the source of truth. HTML declares what depends on it:
<!-- HTML: declare what depends on state -->
<span data-rq-text="count"></span>
<span data-rq-text="count" id="step-tracker"></span>
<div data-rq-show="isDone">All done!</div>
$('#app').rqState({ count: 0, isDone: false });
$('#inc').on('click', () =>
$('#app').rqMutate('count', n => {
const next = n + 1;
$('#app').rqSet('isDone', next >= 10);
return next;
})
);
Adding a new element that displays count? One HTML attribute. No event handler edits.
The handlers only change state — they no longer care about the DOM.
reQuery is not for greenfield SPA development. For that, use Vue, React, or Svelte.
State lives in a WeakMap keyed to the root element — not a global store. Two
widgets on the same page have fully independent state.
When state changes, reQuery walks the subtree, finds data-rq-* bindings for
the changed key, and updates those nodes directly. No diffing, no reconciler.
All methods on $.fn, selector-first, read methods return values, write
methods return this for chaining.
Add these attributes to any element inside your root and reQuery keeps them in sync automatically.
| Attribute | Effect |
|---|---|
data-rq-text="key" |
Sets textContent |
data-rq-html="key" |
Sets innerHTML |
data-rq-val="key" |
Sets input value; also wires input/change for two-way
binding |
data-rq-show="key" |
Toggles visibility via display based on truthiness |
data-rq-attr-[name]="key" |
Sets an HTML attribute; passes null to remove it |
data-rq-class-[name]="key" |
Adds or removes a CSS class based on truthiness |
data-rq-each="key" |
Clones a <template> child for each item in an array |
data-rq-on-[event]="action" |
Wires an event to a named handler from opts.actions |
All methods are registered on $.fn and follow
standard jQuery chaining patterns.
| Method | Returns | Description |
|---|---|---|
rqState(obj, opts?) |
this |
Initialize state on an element; runs initial binding pass |
rqGet(key) |
value | Read a state value |
rqSet(key, value) |
this |
Write a state value; triggers watchers and DOM update |
rqMutate(key, fn) |
this |
Update state via callback — receives current value, returns next |
rqWatch(key, fn) |
this |
Register a callback that fires after state is written |
rqComputed(key, fn) |
this |
Register a derived value; re-runs whenever dependencies change |
reQuery fills a specific gap. It's not trying to be React.
| reQuery | Vanilla jQuery | Vue / React / Svelte | |
|---|---|---|---|
| Requires a build step | No | No | Yes |
| Requires rewriting existing code | No | — | Yes |
| Reactive data binding | Yes | No | Yes |
| Virtual DOM / diffing | No | No | Yes (React, Vue) |
| Works inside CMS-rendered HTML | Yes | Yes | Difficult |
| Full SPA capability | No | No | Yes |
| Bundle size (approx.) | ~5 KB | ~30 KB | 30–100+ KB |
Drop it in via script tag — no bundler required.
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script src="dist/requery.umd.js"></script>
import $ from 'jquery';
import 'requery';
<div id="app">
<p>Count: <strong data-rq-text="count"></strong></p>
<button id="inc">+</button>
</div>
<script>
$('#app').rqState({ count: 0 });
$('#inc').on('click', () => $('#app').rqMutate('count', n => n + 1));
</script>
No compilation. No configuration. No framework to learn.