Overview

Mates event hooks follow one contract: call them in the outer function, and listeners / timers are removed automatically on unmount. You never call removeEventListener yourself.

Most handlers may return a cleanup function — it runs before the next invocation and on unmount. Nearly all DOM/window hooks are SSR no-ops (return early when isServer()).

Lifecycle mount/paint/error hooks live under Lifecycle. This section covers browser APIs scoped to the component host.

Hook groups

Group
APIs
Scope
Ready / update onDOMReady, onUpdate After render (microtask) / sync after flush
Timers onInterval, onTimeout, onCountdown Component-scoped; return TimerHandle / Countdown
Size / scroll onResize, onScroll, onWindow* Host ResizeObserver or window listeners
Input keyboard, focus, click-away Window / document, auto-cleaned
I/O files, clipboard, socket, storage Drop, paste, ws, cross-tab storage
Generic window onWindow, onWindowCapture Any WindowEventMap (+ wheelUp/Down)

Timers — onInterval

Component-scoped interval that clears itself on unmount.

import { html, atom, onInterval, renderApp } from 'mates';

const Clock = () => {
const time = atom(new Date().toLocaleTimeString());

onInterval(() => {
time.set(new Date().toLocaleTimeString());
}, 1000);

return () => html`
<div class="m-col m-gap m-items-center">
<h1 class="mono card-title">${time()}</h1>
<p class="label">onInterval — auto-clears on unmount</p>
</div>
`;
};

renderApp(Clock, document.getElementById('app'));

Keyboard — onKeyDown

Window keydown while the component is mounted. Click the preview first.

import { html, atom, onKeyDown, renderApp } from 'mates';

const Keys = () => {
const last = atom('—');

onKeyDown((e) => {
last.set(e.key === ' ' ? 'Space' : e.key);
});

return () => html`
<div class="m-col m-gap m-items-center">
<p class="muted">Click preview, press a key</p>
<h1>${last()}</h1>
</div>
`;
};

renderApp(Keys, document.getElementById('app'));