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<T>() / 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)): () => voidRun 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): TRun `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): TRun `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): () => voidRegister 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". |