Skip to main content

Assumptions and limits

These are design boundaries, not known bugs.

Browser and React timers​

The hooks use recursive setTimeout with timestamp math. If a tab, browser, or JavaScript thread delays a timeout, the next snapshot catches up from the current timestamp.

Scheduled callbacks are not background jobs. They run while JavaScript is allowed to run.

UI cadence and schedule cadence​

updateIntervalMs is the fallback UI cadence. If a schedule is faster than updateIntervalMs, the scheduler wakes at the schedule cadence so the callback receives accurate timing context.

Use a slower everyMs for expensive polling. Use overlap: 'skip' when async work should not overlap.

Error handling​

onError handles onEnd failures.

Schedule onError handles that schedule's callback failures. If a schedule omits onError, the timer or timer-group item onError is used.

Errors thrown inside your own error handler remain application-owned.

Controlled inputs​

For useTimerGroup({ items }), pass a new array/object when item definitions change. In-place mutation is intentionally not tracked.

For root useTimer() and useScheduledTimer(), autoStart is a mount-time convenience. Use start(), restart(), reset({ autoStart: true }), pause(), and cancel() for runtime state changes.

Server rendering​

Snapshots include Date.now(). If the rendered timestamp must match exactly across server and client, render a placeholder during SSR or start the timer after mount.

Library boundaries​

Formatting, timezone conversion, retry/backoff policy, caching, and data fetching state stay in your app or data layer. The library provides timer state, controls, schedules, diagnostics, and duration math.