Overview

onAllMount(fn) registers a callback that runs once after the current component and every descendant have finished their initial mount. Internally it uses the scheduler's idle queue (onceIdle), so it fires when the subtree is fully registered.

Unlike onMount, which runs as soon as this component's DOM is ready (children may still be mounting), onAllMount waits for the whole tree. That makes it the right hook for analytics “time to interactive”, layout passes that measure child nodes, or enabling features that depend on child readiness.

If fn returns a function, that cleanup is registered and runs on unmount — same pattern as sync onMount.

onMount vs onAllMount

API
Waits for children?
Use when
onMount(fn) No This component's DOM is ready. Self-contained setup, timers, focus.
onAllMount(fn) Yes — entire subtree Analytics, layout that needs child DOM, feature gates after hydration.

onAllMount — wait for all children

The Dashboard's onAllMount callback fires only after Widget A, B, and C have all completed their own onMount. This guarantees the entire subtree is hydrated before the callback runs.

import { html, atom, onMount, onAllMount, x, renderApp } from 'mates';

const ChildWidget = (propsFn) => {
const ready = atom(false);

onMount(() => {
setTimeout(() => ready.set(true), Math.random() * 600 + 200);
});

return () => html`
<div class="card card-body m-flex m-gap-sm m-items-center m-justify-between">
<span>${propsFn().name}</span>
<span class="tag ${ready() ? 'tag-success' : 'tag'}">
${ready() ? 'ready' : 'loading...'}
</span>
</div>
`;
};

const Dashboard = () => {
const allReady = atom(false);

onAllMount(() => {
allReady.set(true);
});

return () => html`
<div class="m-col m-gap">
<h2 class="m-0">Dashboard</h2>
${x(ChildWidget, { name: 'Widget A' })}
${x(ChildWidget, { name: 'Widget B' })}
${x(ChildWidget, { name: 'Widget C' })}
<div class="tag ${allReady() ? 'tag-success' : 'tag'} m-self-start">
${allReady() ? '✓ All children mounted' : 'Waiting for children...'}
</div>
</div>