Skip to content
Ilha
Esc
navigateopen⌘Jpreview
On this page

Core package reference

Compact reference for the public exports from the ilha package.

Use this page as a map of the public ilha API. Start with Introduction if you are building your first island.

Create an island

Import the callable ilha export:

import { 
const ilha: RootBuilder & DirectIslandFactory & {
    html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
    raw: (value: string) => RawHtml;
    mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
    from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
    ... 6 more ...;
    onUncaughtError: typeof onUncaughtError;
}
ilha
} from "ilha";
const const Status: Island<RootInput, RootState>Status = ilha<RootInput>(fn: (ctx: RenderContext<RootInput, RootState, RootDerived, RootActions>) => string | RawHtml): Island<RootInput, RootState>ilha(() => <"p": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLParagraphElement>>p>Ready</"p": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLParagraphElement>>p>); const
const Greeting: Island<{
    name: string;
}, RootState>
Greeting
=
ilha<{
    name: string;
}>(fn: (ctx: RenderContext<{
    name: string;
}, RootState, RootDerived, RootActions>) => string | RawHtml): Island<{
    name: string;
}, RootState>
ilha
<{ name: stringname: string }>(({
input: {
    name: string;
}
input
}) => (
<"p": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLParagraphElement>>p>Hello, {
input: {
    name: string;
}
input
.name: stringname}</"p": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLParagraphElement>>p>
));

ilha(renderFn) is shorthand for ilha.render(renderFn). ilha<Props>(renderFn) is shorthand for .input<Props>().render(renderFn).

Use the builder when the island needs local capabilities:

const Counter = ilha
  .state("count", 0)
  .action("increment", (_, { state }) => {
    state.count((count) => count + 1);
  })
  .render(({ state, action }) => (
    <button onclick={action.increment}>
      Count: {state.count()}
    </button>
  ));

Builder chain

Call .render() exactly once and last.

API Purpose Learn more
ilha.input&lt;T&gt;() / ilha.input(schema) Define typed, defaulted, or validated input props. Input
.as(tag) Choose the wrapper tag when this island is a child slot. Render
.state(key, initial?) Add local reactive state. State
.derived(key, fn) Add synchronous or abortable asynchronous derived data. Derived
.stream(key, fn) Feed a state key from a generator (first value in SSR). Stream
.action(key, fn) Add a typed reusable operation with reactive status. Actions
.on(selector, handler) Add an advanced delegated or host event listener. .on()
.effect(fn) Run a reactive client effect with cleanup and cancellation. Effect
.onMount(fn) Run client setup once per mount and return optional cleanup. On mount
.onError(fn) Handle errors from this island. On error
.transition(options) Add enter and leave lifecycle transitions. Transition
.css(styles) Attach styles scoped to the island host. CSS
.render(fn) Finish the builder and return an Island. Render

Declare actions before callbacks that consume them. Prefer lowercase native event props for element-owned events; reserve .on() for selectors, host listeners, full handler context, or combined modifiers.

Island methods

A completed island is callable and also exposes explicit rendering and lifecycle methods.

API Purpose
Island.toString(props?) Render synchronously to HTML.
await Island(props?) Render to HTML when asynchronous children or derived data may exist.
Island.mount(host, props?) Render and mount into one host; returns an unmount function.
await Island.hydratable(props, options) Emit hydration markup with a name and optional state snapshot.
Island.key(key)(props?) Create a keyed child invocation for reorderable or conditional lists.
Island.define(tagName, options?) Register the island as a custom element.

Use mount({ Counter }) when the server already emitted named [data-ilha] hosts. Use Counter.mount(host, props) to render directly into one client host.

Helpers from ilha

import {
  const mount: (registry: IslandRegistry, options?: MountOptions) => MountResultmount,
  const html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtmlhtml,
  const raw: (value: string) => RawHtmlraw,
  const css: (strings: TemplateStringsArray | string, ...values: (string | number)[]) => stringcss,
  function signal<T>(initial: T): SignalAccessor<T>
Create a free-standing reactive signal that lives outside any island. Useful for sharing state across islands without prop drilling, or for binding form inputs to module-level state via the `bind:value=${signal}` template syntax. The returned accessor is a getter when called with no arguments and a setter when called with one. Reading it inside a `.derived()`, `.effect()`, or `.render()` automatically subscribes the surrounding reactive scope — so when the signal changes, dependents re-run as if it were local state.
signal
,
function computed<T>(fn: () => T): SignalAccessor<T>
Create a free-standing read-only reactive value derived from other signals. The computation is lazy and cached: `fn` re-runs only when a signal it read changed and the computed is read again. Reading it inside a `.derived()`, `.effect()`, `.render()`, or top-level `effect()` subscribes that scope — dependents re-run when the computed's value changes. ```ts const items = ilha.signal([1, 2, 3]); const total = ilha.computed(() => items().reduce((a, b) => a + b, 0)); ```
computed
,
function effect(fn: () => void | (() => void)): () => void
Run a free-standing reactive effect outside any island. `fn` runs once immediately and again whenever a signal it read changes. It may return a cleanup function, invoked before each re-run and on stop. Signal writes inside the effect are batched. Returns a stop function that disposes the effect and runs the final cleanup. ```ts const stop = effect(() => { document.title = `${cart.count()} items`; }); ```
effect
,
const context: (<T>(key: string, initial: T) => ContextSignal<T>) & {
    delete(key: string): boolean;
    clear(): void;
}
context
,
function batch<T>(fn: () => T): T
Run `fn` as an atomic batch — multiple signal writes inside the callback produce a single propagation pass, so dependents (effects, deriveds, island re-renders) see the final state and run once instead of once per write. Returns whatever `fn` returns. Note: `.on()` handlers and `.effect()` runs are batched implicitly, so you only need this when triggering multiple writes from outside an island (e.g. from a top-level event listener or async callback).
batch
,
function untrack<T>(fn: () => T): T
Run `fn` with reactive tracking suspended. Reading signals inside `fn` returns their current value without subscribing the surrounding scope. Use this in effects/deriveds when you want to peek at state without causing a re-run on its changes.
untrack
,
const from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | nullfrom, function onUncaughtError(fn: (error: Error, source: ErrorSource) => void): () => void
Register a global error handler invoked when any island reports an error (from .on, .effect, .onMount, or transitions) and has no local .onError() handler. Returns an unsubscribe function. Islands with their own .onError() are handled locally and do not reach the global sink.
onUncaughtError
,
} from "ilha";
Export Purpose Learn more
mount(registry, options?) Discover and mount named island hosts in the browser. Mount
html\…`` Create escaped RawHtml template output. HTML
raw(value) Mark a trusted string as unescaped RawHtml. Raw
css\…`` Create reusable CSS text for .css(). CSS helper
signal(initial) Create a standalone readable and writable signal. Signals
computed(fn) Create a lazy, cached, read-only value from signals. Signals
effect(fn) Run a standalone reactive effect; returns a stop function. Signals
context(key, initial) Get or create a keyed shared signal. Signals
context.delete(key) Remove one key from the context registry. Signals
context.clear() Clear the context registry, commonly between tests or HMR runs. Signals
batch(fn) Batch signal writes into one propagation pass. Signals
untrack(fn) Read signals without subscribing the active reactive scope. Signals
from(selector, island, props?) Mount an island into an existing selector or element. Mount
onUncaughtError(fn) Register a global fallback for otherwise uncaught island errors. On error

Signal setters accept a value or updater:

count(1);
count((previous) => previous + 1);

A function argument is interpreted as an updater. Wrap function-valued replacements:

callback(() => nextCallback);

Actions

An action receives its payload first and context second:

.action("save", async (draft: Draft, { state, derived, input, host, signal }) => {
  const response = await fetch("/api/save", {
    method: "POST",
    body: JSON.stringify(draft),
    signal,
  });
  state.saved(await response.json());
})

Each action accessor is callable and exposes reactive status properties:

action.save.pending;
action.save.data;
action.save.error;

Native event props

Use lowercase DOM event names in JSX:

<button onclick={action.save}>Save</button>
<input oninput:abortable={(event, { signal }) => search(event, signal)} />

Handlers receive the native event and { signal }. Add at most one native modifier: :abortable, :once, :capture, or :passive.

JSX runtime

Use the automatic runtime with a pragma or tsconfig.json:

/** @jsxImportSource ilha */
{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "ilha"
  }
}

Build tools resolve ilha/jsx-runtime in production and ilha/jsx-dev-runtime in development.

Intrinsic props are element-specific. Native event currentTarget and bind:* accessors use the element’s concrete DOM type. RawHtml is accepted by string-valued HTML and SVG attributes:

<img src={raw(icon)} alt="Icon" />
<svg>
  <use href={raw("#icon")} xlinkHref={raw("#icon")} />
</svg>

Common public types

import type {
  Island,
  KeyedIsland,
  RawHtml,
  HydratableOptions,
  MountOptions,
  MountResult,
  SignalAccessor,
  SignalSetter,
  SignalWriter,
  ExternalSignal,
  IslandState,
  IslandDerived,
  DerivedAccessor,
  DerivedValue,
  ActionAccessor,
  IslandActions,
  ActionContext,
  HandlerContext,
  HandlerContextFor,
  NativeEventHandler,
  NativeEventContext,
  NativeEventModifier,
  EffectContext,
  OnMountContext,
  ErrorContext,
  ErrorSource,
} from "ilha";
Type Use it for
Island A callable, renderable, mountable island.
KeyedIsland A keyed child invocation returned by Island.key().
RawHtml Trusted HTML produced by html or raw.
HydratableOptions Hydration name and snapshot options.
MountOptions Registry mounting root and lazy behavior.
MountResult Registry mount result, including its unmount() function.
SignalAccessor A readable and writable signal, including .select().
SignalSetter A direct value or functional updater accepted by writable signals.
SignalWriter The write target used by typed bindings such as bind:this.
ExternalSignal A standalone signal accepted by templates and bind:*.
IslandState Local state accessors exposed to island callbacks.
IslandDerived Named derived accessors exposed to island callbacks.
DerivedAccessor A derived value accessor with loading and error information.
DerivedValue The { loading, value, error } envelope behind a derived accessor.
ActionAccessor A callable action with .pending, .data, and .error.
IslandActions The typed action map exposed to island callbacks.
ActionContext State, derived data, input, host, and abort signal passed to an action.
HandlerContext Full context passed to advanced .on() listeners.
HandlerContextFor Event-specific .on() context with typed event and target.
NativeEventHandler Lowercase native event-prop handler type.
NativeEventContext Native handler lifecycle context containing signal.
NativeEventModifier "abortable", "once", "capture", or "passive".
EffectContext Context passed to .effect().
OnMountContext Context passed to .onMount().
ErrorContext Context passed to .onError().
ErrorSource "on", "effect", "mount", "transition", or "action".
Package Guide
@ilha/router Router
@ilha/store Store
@ilha/astro Astro

Was this page helpful?