n nisli
GitHub

Components

component() defines a real custom element and returns a typed factory for composition.

Props are signals

Declare props as a TypeScript interface. Inside setup, every prop is a Signal — read .value or use it in a template. The setup function must be synchronous.

import { component, computed, html } from '@nisli/core';

interface GreetingProps { name: string }

const Greeting = component<GreetingProps>('x-greeting', (props) => {
  const upper = computed(() => props.name.value.toUpperCase());
  return html`<p>Hello, ${upper}</p>`;
});

Factory composition

Calling Greeting({ name: 'nisli' }) returns a template you compose into other components. Pass a plain value for static props, or a signal to stay reactive.

Lifecycle

onMount() runs after the element connects; onCleanup() runs on teardown. Effects created in setup are disposed automatically.

import { component, onMount, onCleanup, html } from '@nisli/core';

component('x-clock', () => {
  onMount(() => {
    const id = setInterval(tick, 1000);
    onCleanup(() => clearInterval(id));
  });
  return html`<time></time>`;
});