n nisli
GitHub

Quick start

Three imports — a signal, a component, and an html template — build a working reactive counter. No build step required.

Define a component

component() registers a real custom element. Inside the setup function, signal() creates reactive state; the html`` template wires it to the DOM.

counter.ts
import { signal, component, html } from '@nisli/core';

component('x-counter', () => {
  const count = signal(0);

  return html`
    <button @click=${() => count.value++}>
      Count: ${count}
    </button>
  `;
});

Use it

Importing the module registers the <x-counter> element. Drop the tag in your HTML — it upgrades automatically. No hydration step, no root render call.

index.html
<script type="module" src="./counter.ts"></script>

<x-counter></x-counter>

Clicking the button mutates count.value; the ${count} binding is the only thing that updates. That is fine-grained reactivity — no re-render, no diff.

What next

Learn how reactivity works (/docs/signals), how templates bind (/docs/templates), and how to compose components (/docs/components).