Skip to content

Alacris

Web components with signals and fine-grained DOM updates — in 6 kB. ESM-only, zero dependencies, and no build step to adopt it.

No bundler, no config, no build step. The element below is running the real library, loaded from this page.

Try itrunning the real bundleEdit in playground
counter.js
import { define, html, signal } from '@alacris/core';
define('demo-counter', {
props: { start: 0, step: 1 },
styles: `
:host { display: inline-flex; align-items: center; gap: .75rem; font: inherit }
button { font: inherit; padding: .3rem .7rem; border-radius: 6px; cursor: pointer;
border: 1px solid currentColor; background: transparent; color: inherit }
output { font-variant-numeric: tabular-nums; font-size: 1.4rem; min-width: 3ch;
text-align: center; font-weight: 700 }
`,
setup({ start, step }) {
const count = signal(start());
return html`
<button @click=${() => count(count() - step())} aria-label="decrement">&minus;</button>
<output>${count}</output>
<button @click=${() => count(count() + step())} aria-label="increment">+</button>`;
},
});

Every example on this site works the same way: the code you read is executed on the page, imported from the published bundle under its real specifier. Nothing is transcribed by hand, so nothing can quietly fall out of date.

Signals, not re-renders

A component’s setup runs once. After that every binding is its own subscription, so changing a value writes to exactly one attribute or one text node. No virtual DOM, no diffing, no component re-render.

Actually small

6.56 kB gzipped for the whole runtime — reactivity, templates, styling and the custom-element layer. The store and context add-ons are 1.03 kB and 0.54 kB, and you only pay for what you import.

Styling that other people can use

Custom properties, ::part and adoptable stylesheets, so a consumer can theme your components without forking them. Verified against a real CSS engine, not assumed.

It is just a tag

The output is a standards custom element. React, Vue, Svelte, Angular, Rails and Django already know how to render it — there is nothing to integrate.