Ultra-fast Alpine.js alternative powered by TC39 Signals. 3.6KB gzipped, 5-10x faster.
npm install @farhanaliraza/k2-jsUltra-fast Alpine.js alternative powered by TC39 Signals



K2 is a lightweight reactive framework that brings Alpine.js-style declarative HTML with the performance of TC39 Signals. At just 3.6KB gzipped, it's ~4.7x smaller than Alpine.js and ~1.7x smaller than Petite-Vue.
- Tiny: 3.6KB gzipped (vs Alpine.js 17KB, Petite-Vue 6KB)
- Fast: Built on TC39 Signals for fine-grained reactivity
- Familiar: Alpine.js-compatible directive syntax
- Zero dependencies: No runtime dependencies
- TypeScript: Full TypeScript support
``html`
`bash`
npm install @farhanaliraza/k2-jsor
pnpm add @farhanaliraza/k2-js
`js`
import K2 from '@farhanaliraza/k2-js';
`html
`
K2 auto-initializes when the DOM is ready. For manual control:
`js`
K2.init(); // Initialize all x-data components
K2.init(myElement); // Initialize within a specific element
Define reactive state for a component:
`html`
Set element text content:
`html`
Set element inner HTML:
`html`
Toggle element visibility:
`html`Shown when isVisible is true
Bind attributes dynamically:
$3
Two-way data binding for inputs:
`html
`$3
Handle events:
`html
Only direct clicks
`Computed Properties
Define computed values as functions in x-data:
`html
`Programmatic API
K2 exports its signal primitives for advanced use:
`js
import { State, Computed, effect, untrack } from '@farhanaliraza/k2-js';// Create reactive state
const count = new State(0);
console.log(count.get()); // 0
count.set(5);
// Create computed values
const doubled = new Computed(() => count.get() * 2);
console.log(doubled.get()); // 10
// Create effects (auto-run when dependencies change)
const dispose = effect(() => {
console.log('Count is:', count.get());
});
// Stop tracking inside untrack
untrack(() => {
count.get(); // Not tracked
});
// Cleanup
dispose();
`Benchmarks
K2 outperforms Alpine.js across all benchmarks:
| Benchmark | K2 | Alpine.js | K2 Faster By |
|-----------|-----|-----------|--------------|
| Create 1,000 rows | 15ms | 85ms | 5.7x |
| Update every 10th | 2ms | 35ms | 17.5x |
| Clear 1,000 rows | 1ms | 25ms | 25x |
| Select row | 0.5ms | 15ms | 30x |
Results vary by browser and hardware. Run
benchmarks/index.html to test yourself.$3
1. Signals vs Proxies: K2 uses TC39 Signals which notify subscribers directly when values change. Alpine.js uses Proxies which require checking all possible dependents.
2. Fine-grained updates: Only the specific DOM nodes that depend on changed data are updated.
3. Smaller bundle: Less code to parse and execute on page load.
Browser Support
K2 supports all modern browsers (Chrome, Firefox, Safari, Edge).
Development
`bash
Install dependencies
pnpm installRun tests
pnpm testBuild
pnpm buildDev server with watch
pnpm devCheck bundle size
pnpm size
``MIT