Compare · Pulse · Alpine-style

jsKjs vs Alpine.js

Pulse brings Alpine's "state in the markup" model to jsKjs: kj-data, kj-text, kj-show, kj-model, @event, :attr, components and stores. It is deliberately smaller than Alpine.

Choose jsKjs when…
  • Your components are toggles, forms, wizards, counters, tabs and carts.
  • You want reactivity plus a jQuery API, hypermedia and animation in one file.
Choose Alpine.js when…
  • You need x-for keyed list rendering or x-if templates.
  • You rely on magics ($watch, $dispatch, $refs, $nextTick) or plugins (persist, focus, intersect, collapse).
  • You want x-transition or a CSP-safe build.

Feature by feature

Compared with Alpine.js 3.17.5. ✓ works the same · ◐ supported with differences · ✗ not included.

Alpine.js features and jsKjs support
Alpine.jsjsKjsNotes
x-data (object, init())✓ Yeskj-data; init(el) receives the root element.
Alpine.data with arguments✓ Yes$.component(name, factory) + kj-data="name(args)".
Alpine.store / $store◐ Partial$.store(name, data); read as $.store("name") — no $store magic.
Alpine.reactive✓ Yes$.reactive(obj).
x-text / x-html✓ Yeskj-text / kj-html.
x-show✓ Yeskj-show.
x-model◐ Partialkj-model for text, number, range, textarea, select, checkbox, radio. No .number/.lazy/.debounce modifiers.
x-on / @ with .prevent .stop and key modifiers◐ Partial@event / kj-on:event with one modifier: .prevent, .stop, .enter, .escape.
@ modifiers .outside .window .document .once .debounce .throttle .self✗ No
x-bind / : (string values)✓ Yes:class merges with static classes; false/null removes the attribute.
x-bind object syntax for :class / :style✗ NoUse string expressions.
$el, $event✓ Yes
x-for, x-if✗ NoRender lists with kj-html + .map().join("") and $.escape().
x-init, x-effect, x-ref / $refs, x-cloak, x-ignore, x-teleport, x-id, x-modelable✗ No
x-transition✗ NoAnimate with Motion ($.to / $.from).
$watch, $dispatch, $nextTick, $root, $data, $id✗ NoUse custom events (.trigger) and setTimeout.
Plugins (persist, intersect, focus, collapse, mask, morph, anchor)✗ No
CSP build✗ NoPulse uses new Function; strict CSP needs unsafe-eval.

Same component, renamed

HTML
<!-- Alpine -->
<div x-data="{ open: false }"><button @click="open = !open">Menu</button><ul x-show="open">…</ul></div>
<!-- jsKjs -->
<div kj-data="{ open: false }"><button @click="open = !open">Menu</button><ul kj-show="open">…</ul></div>

See every Pulse feature live →