@robonen/vue
A collection of 213+ tree-shakeable, SSR-safe composables for Vue 3 — reactive primitives for state, sensors, the DOM, browser APIs, animation, forms and more.
Every Vue app ends up re-implementing the same building blocks: a toggle, a debounced ref, an event listener that cleans itself up, a media query, local-storage state. @robonen/vue ships those building blocks as small, composable functions with a consistent API. Each one is independently tree-shakeable, written in TypeScript with full inference, and safe to call during server-side rendering — guards for window, document and navigator are built in, so the same code runs on the server and hydrates cleanly on the client.
Tree-shakeable by design
Import only what you use. Each composable lives on its own and pulls in nothing it doesn't need — your bundle stays exactly as small as your usage.
SSR-safe out of the box
Browser-only access is guarded behind lifecycle hooks and configurable window/document targets, so Nuxt and SSR setups just work.
Fully typed
Written in TypeScript with precise return types and generics. MaybeRefOrGetter arguments mean you can pass plain values, refs or getters interchangeably.
Broad coverage
From state and reactivity to sensors, elements, storage, math and form handling — one cohesive toolkit spanning the whole surface of a Vue app.
Install
pnpm add @robonen/vueQuick start
Import the composables you need and use them inside <script setup>. Here's a counter clamped to a range, with auto-cleaning keyboard shortcuts:
import { useCounter, useEventListener, useToggle } from '@robonen/vue';
// Clamped, reactive counter
const { count, increment, decrement, reset } = useCounter(0, { min: 0, max: 10 });
// A boolean toggle with custom truthy/falsy values
const { value: theme, toggle } = useToggle('light', {
truthyValue: 'dark',
falsyValue: 'light',
});
// Listener is removed automatically on unmount
useEventListener('keydown', (e) => {
if (e.key === 'ArrowUp') increment();
if (e.key === 'ArrowDown') decrement();
});The same useCounter running live:
Where to next
The full API reference is listed right below. A few good starting points:
- useCounter — a clamped, reactive counter with increment / decrement / set / reset.
- useToggle — a boolean toggle with customizable truthy / falsy values.
- useEventListener — declarative event listeners that clean up on unmount.
- useStorage — reactive state synced to
localStorage/sessionStorage. - useMagicKeys — reactive keyboard state for building shortcuts.
API Reference
Animation · 33
Cubic bezier control points `[x1, y1, x2, y2]` (the implied endpoints are `(0, 0)` and `(1, 1)`), matching the CSS `cubic-bezier()` argument order.
Signature for a custom meridiem (AM/PM) formatter.
Accepted input for {@link useDateFormat}: a `Date`, a millisecond timestamp, a parseable date string, or `null`/`undefined` (resolves to "now").
An easing function mapping linear progress in `[0, 1]` to eased progress.
Format a `Date` against a token string. Exposed for one-shot, non-reactive formatting; {@link useDateFormat} wraps this in a `computed`.
Pure (non-reactive) relative-time formatter. Useful on its own and reused by `useTimeAgo` on every tick.
Options shared by the pure `formatTimeAgo` and the reactive `useTimeAgo`.
Coerce a {@link DateLike} into a `Date`. `null`/`undefined` become the current time; a non-UTC string is parsed leniently so partial dates such as `'2024-3'` are accepted.
The transition easing: either a cubic bezier tuple or a custom easing function.
Interpolates between two values of `T` given an eased progress `alpha`.
Values that can be transitioned: a single number or a fixed-length number array.
Reactive [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API) wrapper for a single element. Exposes imperative controls (`play`, `pause`, `reverse`, `finish`, `cancel`) alongside reactive state (`playState`, `currentTime`, `playbackRate`, ...). The reactive state is synced via `requestAnimationFrame` only while the animation is running, so an idle animation costs nothing. SSR-safe: nothing touches the DOM until the element resolves.
Reactive countdown timer exposing the remaining seconds plus `start`/`stop`/`pause`/`resume`/`reset` controls and `onTick`/`onComplete` callbacks. Built on `useIntervalFn`, so it is SSR-safe and cleans up on scope dispose.
Reactively format a `Date`, timestamp, or date string against a token string (`YYYY MM DD HH mm ss SSS dddd A` etc.). Recomputes when the date, format, or locale changes.
Reactive formatted date string.
Reactive counter that increments on every interval tick.
Call a function on every interval. Supports reactive interval duration, pause/resume, and automatic cleanup on scope dispose.
Reactive current `Date`, updated via `requestAnimationFrame` or a fixed interval.
Pause/resume controls returned when `controls: true`.
Call a function on every `requestAnimationFrame` with delta time tracking. Automatically cleans up when the component scope is disposed.
Reactive relative time string (e.g. `'3 minutes ago'`) that ticks on a fixed interval. Fully customizable messages (i18n), units, rounding, and an automatic fallback to a full date once `max` is exceeded.
Controls returned when `controls: true`.
Formatter for a single unit value. Receives the rounded numeric value and whether the instant is in the past, and returns the localized fragment.
Full message map: the built-in slots plus a formatter per unit name.
Built-in (non-unit) message slots.
Options for `useTimeAgo`.
A single time unit used while resolving the most appropriate granularity.
The default set of unit names recognized by `useTimeAgo`.
Reactive boolean that flips to `true` after a given delay. Built on `useTimeoutFn`; optionally exposes `start`/`stop` controls. SSR-safe.
Call a function after a given delay, with manual `start`/`stop` control and a reactive `isPending` flag. SSR-safe and cleans up on scope dispose.
Reactive current timestamp, updated via `requestAnimationFrame` or a fixed interval.
Pause/resume controls returned when `controls: true`.
Reactively transition between numeric values (or numeric arrays) over a duration with configurable easing. Wraps a single, paused `requestAnimationFrame` loop that only runs while a transition is in flight, so it is cheaper than re-creating an RAF loop per change. SSR-safe: without a `window` the output tracks the source synchronously.
Array · 17
Reactive difference of two arrays. Returns items in `list` that are not in `values` (asymmetric), or items in exactly one array (symmetric). Both arrays may be reactive (refs or getters).
Comparator deciding whether two array elements are considered equal.
Reactive `Array.prototype.every`. The source array and its items may be reactive.
Reactive `Array.prototype.filter`.
Reactive `Array.prototype.find`.
Reactive `Array.prototype.findIndex`.
Reactive `Array.prototype.findLast`.
Reactive `Array.prototype.includes` with an optional comparator and `fromIndex`. The source array and its items may be reactive.
Comparator deciding whether an array element equals the searched value.
Reactive `Array.prototype.join`, with an optional reactive separator.
Reactive `Array.prototype.map`.
Reactive `Array.prototype.reduce`, with an optional initial value.
Reactive `Array.prototype.some`. The source array and its items may be reactive.
Reactive de-duplicated array. By default uses `Set` identity (`===`); an optional key of `T`, key extractor (both O(n)), or full comparator (O(n²)) customizes equality. The source array and its items may be reactive. First-seen insertion order is preserved.
Equality comparator deciding whether two array elements are duplicates.
Extracts the comparison key for an element. Two elements that produce the same key (via `===`/`Set` identity) are considered duplicates.
Reactive, stable sorted copy of an array. Mirrors `Array.prototype.sort` but never mutates the source by default and guarantees stable ordering.
Browser · 54
A breakpoints map: name → viewport width. Numbers are treated as pixels; strings keep their unit (`"48em"`, `"30rem"`, `"1024px"`). Values may be reactive (refs or getters).
Creates a custom ref that syncs its value across browser tabs via the BroadcastChannel API
A value to copy: either concrete `ClipboardItems` or an (optionally async) getter that resolves to them.
A value to copy: either a string or an (optionally async) getter that resolves to one.
Handler invoked when a close request is received. The argument is the native `close` event when the platform `CloseWatcher` is used, or the `Escape` `KeyboardEvent` when falling back to keydown.
Subscribe to an event; returns an unsubscribe function.
`window.showOpenFilePicker` parameters.
`window.showSaveFilePicker` parameters.
A `window` augmented with the File System Access API entry points.
A single font face exposed by the [Local Font Access API](https://developer.mozilla.org/en-US/docs/Web/API/FontData).
Permission names not yet present in the lib DOM `PermissionName` union but supported by browsers behind the Permissions API.
Reactive viewport breakpoints derived from a breakpoints map. SSR-safe (resolves width queries from `ssrWidth` before `matchMedia` exists), reactive to breakpoint values, and built on a single `useMediaQuery` per comparison. Comes with presets: `breakpointsTailwind`, `breakpointsBootstrapV5`, `breakpointsAntDesign`, `breakpointsVuetifyV3`.
Which edge a generated shortcut property (e.g. `breakpoints.lg`) reacts to. - `'min-width'` (mobile-first) — `lg` is `true` when the viewport is at least the `lg` width. - `'max-width'` (desktop-first) — `lg` is `true` when the viewport is at most the `lg` width.
Reactive async Clipboard API.
Reactive async Clipboard API with rich `ClipboardItem` support (read/write images, HTML, and arbitrary MIME types — not just text). SSR-safe; uses passive `copy`/`cut` listeners and guards stale async writes.
Wrap the native `CloseWatcher` API to handle close requests (the `Esc` key or the Android back gesture). Falls back to listening for `Escape` keydown when `CloseWatcher` is unavailable. SSR-safe.
Reactive color mode (`light` / `dark` / `auto`) with system detection, storage persistence, and automatic application of a class or attribute to a target element.
Read and write a CSS custom property on an element as a reactive ref. Defaults to `document.documentElement`. Set `observe` to react to external changes via a `MutationObserver`.
Reactive dark mode boolean with system detection and storage persistence, built on `useColorMode`. Writing `false` while the system already prefers light (or `true` while it prefers dark) falls back to `'auto'`, so the mode keeps tracking the OS preference.
Reactive wrapper around the [Document Picture-in-Picture API](https://developer.mozilla.org/en-US/docs/Web/API/DocumentPictureInPicture) for rendering arbitrary DOM in an always-on-top window.
Registers an event listener using the `addEventListener` on mounted and removes it automatically on unmounted Overload 1: Omitted window target
Reactive wrapper around the [EyeDropper API](https://developer.mozilla.org/en-US/docs/Web/API/EyeDropper) for picking colors from the screen.
Reactive favicon.
Open a native file dialog programmatically and reactively track the selected files.
Create, read, and write local files via the File System Access API.
Picker options shared between open/create/save operations.
The supported file data types.
Picker options accepted by save-style operations.
Reactive Fullscreen API for an element (or the document element). Handles vendor-prefixed fallbacks for request/exit/state detection and syncs `isFullscreen` from `fullscreenchange` events. SSR-safe.
Reactively load an image in the browser; await the result to render it or show a fallback.
Reactive wrapper around the [Local Font Access API](https://developer.mozilla.org/en-US/docs/Web/API/Local_Font_Access_API) for enumerating the user's locally installed fonts.
Reactive `window.matchMedia`. SSR-safe, reactive to the query, and with optional SSR width resolution for `min-width` / `max-width` queries.
Create and auto-revoke an object URL for a `Blob`, `File`, or `MediaSource`. The previous URL is revoked whenever the source changes, and the active URL is revoked on scope dispose.
Reactive Permissions API state.
Reactive `prefers-color-scheme` media query.
Reactive `prefers-contrast` media query, resolving to the user's preferred contrast level. SSR-safe with an optional SSR fallback value.
Reactive `prefers-color-scheme: dark` media query.
Reactive `navigator.languages`. Tracks the user's preferred languages and updates automatically whenever the browser emits a `languagechange` event. Falls back to `['en']` during SSR or when no `window` is available, so the returned value is always a non-empty array.
Reactive `prefers-reduced-motion` media query, resolving to `'reduce'` when the user requests reduced motion and `'no-preference'` otherwise. SSR-safe via {@link useMediaQuery}.
Reactive `prefers-reduced-transparency` media query, resolving to `'reduce'` or `'no-preference'`. SSR-safe (defaults to `'no-preference'`).
Dynamically inject and manage a `<script>` tag. The returned `load`/`unload` controls append the element to the document `<head>` (reusing an existing tag with the same `src`) and resolve once the script has loaded. Loading is de-duplicated, listeners are passive, and everything is SSR-safe.
Reactive Web Share API wrapper to invoke the native share sheet.
Inject a reactive `<style>` tag into the document `<head>`. The CSS is a writable ref — assigning to it updates the live stylesheet. Multiple instances sharing an `id` reuse a single element via reference counting, and everything is SSR-safe.
Elects a single leader tab using the Web Locks API. Only one tab at a time holds the lock for a given key. When the leader tab closes or the scope is disposed, another tab automatically becomes the leader.
Auto-resizes a `<textarea>` to fit its content. Reacts to user input, programmatic content changes, and element resize. Reuses `useEventListener` for a passive, auto-cleaned `input` listener and `useResizeObserver` to re-measure when the textarea's width changes (so reflowed text is re-fitted). SSR safe.
Reactive `document.title`. Pass a getter to derive the title from other reactive state (returns a read-only ref), or a plain value/ref for two-way binding.
Reactive `URLSearchParams` exposed as a plain reactive object. Reads from and (optionally) writes back to the URL using the `history`, `hash`, or `hash-params` location source. Listens for `popstate`/`hashchange` with passive listeners and pauses its own writer while syncing to avoid feedback loops. SSR-safe: returns the seeded reactive object when no `window` is available.
Reactive wrapper around the `navigator.vibrate` Vibration API.
Reactive wrapper over the Screen Wake Lock API to keep the screen awake. Re-acquires a deferred lock automatically when the document returns to visible.
Reactive, SSR-safe wrapper around the Web Notification API with permission handling and `onClick`/`onShow`/`onError`/`onClose` event hooks.
Per-notification options mirroring the `Notification` constructor's `NotificationOptions`, plus the `title` argument folded in for convenience.
Component · 9
Define a template once and reuse it multiple times within the same component. Returns a `[DefineTemplate, ReuseTemplate]` pair (also destructurable as `{ define, reuse }`). The template captured by `DefineTemplate`'s default slot is rendered wherever `ReuseTemplate` appears, receiving its props/attrs as slot bindings. Supports a generic for typed bindings, typed slots, custom `props`, and `inheritAttrs`. Render-only and fully SSR-safe — it never touches `window`/`document`. The pair is created lazily and shares a single `shallowRef` for the captured render function, so there are no watchers and no per-render allocations beyond the vnode itself.
The pair returned by {@link createReusableTemplate}. Usable both as a tuple (`const [Define, Reuse] = ...`) and as an object (`const { define, reuse } = ...`).
Unwraps a Vue element reference to get the underlying instance or DOM element.
Reactive root DOM element of the current component instance. Resolves to `vm.$el` (or the unwrapped `rootComponent` ref when provided) and is re-read on `onMounted` and `onUpdated` via a controlled computed — so it stays correct across re-renders without an always-on watcher. Generic over the element type; the type is inferred from the component's `$el` when available. SSR-safe: returns `undefined` until the component is mounted on the client.
Infer the resolved element type. When no explicit generic is supplied (`T` stays the broad `MaybeElement`) we fall back to the component instance's `$el` type — unless that is `any` (the un-typed default), in which case we keep `MaybeElement`.
Forwards a child component's exposed API and DOM element (`$el`) through the parent component. Useful for wrapper / headless components that need to transparently proxy the inner component's ref to the consumer. Merges the parent's own props and any prior `expose()` bindings onto `instance.exposed`, then updates them when `forwardRef` is called with a child element or component instance.
Collects a dynamic list of template refs for use with `v-for`. Automatically clears the list before each component update and repopulates it with fresh element references. Handles both plain DOM elements and Vue component instances (unwraps `$el`). Uses a non-reactive buffer internally to collect refs during the render cycle, then flushes to a `shallowRef` in `onMounted`/`onUpdated` to avoid triggering recursive update loops.
Virtualize a large list so only the items inside (and slightly around) the viewport are rendered. Supports vertical (`itemHeight`) and horizontal (`itemWidth`) layouts, fixed or per-index sizes, and an `overscan` buffer. Backed by `useElementSize` (reactive container size) and `useEventListener` (passive, auto-cleaned scroll handling). SSR-safe: renders an empty window until the container mounts.
Fixed pixel size or a per-index getter.
Debug · 2
Elements · 18
Fire a callback when the target element — or any ancestor containing it — is removed from the DOM. Backed by a single `childList`/`subtree` `MutationObserver` on the element's owning document, so it also catches removal of a parent further up the tree.
Reactive `document.activeElement`, traversing open shadow roots.
Reactive `document.readyState` (`loading` | `interactive` | `complete`), updated on `readystatechange`.
Reactive `document.visibilityState`.
Make an element draggable by pointer, tracking its position with optional axis locking, a drag handle, container constraints, and lifecycle callbacks. SSR-safe and built on passive pointer listeners.
Create a drag-and-drop file drop zone on a target element or document.
Reactive bounding box of an element (`getBoundingClientRect`), kept in sync via `ResizeObserver`, `MutationObserver`, and window scroll/resize. Supports deferring reads to the next animation frame to avoid layout thrash.
Reactive size of an element, backed by `ResizeObserver`. Measures synchronously on mount, handles SVG elements via `getBoundingClientRect`, and sums multiple box fragments (e.g. multi-column layouts).
Track whether an element is visible within the viewport (or a custom scroll root), backed by `IntersectionObserver`.
Adds a pair of focus guards at the boundaries of the DOM tree to ensure consistent focus behavior
Detect when an element enters or leaves the viewport via `IntersectionObserver`. Accepts a single target, an array of targets, or a ref/getter resolving to either, plus reactive `rootMargin` and `threshold`.
Watch for changes to the DOM tree via `MutationObserver`. Accepts a single target, an array of targets, or a getter returning either.
Reactive `parentElement` of a given element (or the current component instance's root element when no target is supplied). Resolves the target through `unrefElement`, so it accepts plain elements, template refs, component instances, getters and computed refs. A single `immediate` watcher tracks the resolved target and re-reads its parent only when the element itself changes — no extra lifecycle hooks or always-on observers. SSR-safe: stays `undefined` until the target is resolved on the client.
Reports changes to the dimensions of an element via `ResizeObserver`. Accepts a single target or an array of (reactive) targets. The observer is recreated only when the resolved elements change, and can be paused/resumed.
Reactively track whether the window is focused via `focus`/`blur` events.
Reactive window scroll position with arrived/direction tracking. Writing to `x`/`y` scrolls the window.
Reactive window size. Tracks the inner viewport, the outer window, or the visual viewport (pinch-zoom aware), and reacts to resize and orientation changes.
Which window dimensions to track. - `'inner'` — `window.innerWidth/innerHeight` (or `documentElement.clientWidth/clientHeight` when `includeScrollbar` is `false`). The viewport size. - `'outer'` — `window.outerWidth/outerHeight`. The whole browser window, including chrome. - `'visual'` — `window.visualViewport` size, accounting for pinch-zoom scale. Useful on mobile where the visual viewport differs from the layout viewport.
Forms · 4
Bind a single field by path. When rendered under a {@link useForm}(or given an explicit `form`), it reads/writes that form's state; otherwise it runs standalone with its own value, errors, and validation. Returns a writable `value`, reactive errors/meta, blur/change handlers, and `attrs` to spread.
Manage a dynamic array field within a {@link useForm}. Exposes a reactive `fields` list with **stable keys** (preserved across reorders, so `v-for :key` keeps DOM/state intact) plus immutable `push`/`prepend`/`insert`/ `remove`/`move`/`swap`/`replace`/`update` operations that also re-key the matching errors and touched state.
Headless, performant form state management. Holds reactive `values`, flat path-keyed `errors`/touched maps, derived `meta`, and a full set of mutation/validation/submit/reset helpers. Validation accepts a [Standard Schema](https://github.com/standard-schema/standard-schema) (zod/valibot/arktype), a custom resolver, or per-field function validators.
Retrieve the {@link useForm} instance provided by an ancestor, for building field components that live anywhere in the form's subtree. Returns `null` when no form has been provided (so callers can support standalone use).
Lifecycle · 4
Call onBeforeMount if it's inside a component lifecycle hook, otherwise just calls it
Call onMounted if it's inside a component lifecycle hook, otherwise just calls it
A composable that will run a callback when the scope is disposed or do nothing if the scope isn't available.
Returns a ref that tracks the mounted state of the component (doesn't track the unmounted state)
Math · 23
Create a reusable projection between two arbitrary (non-numeric) domains using a custom projector. The returned factory turns a reactive input into a `ComputedRef` of the projected value, so the same projection can be applied to many inputs without re-resolving the domains each time.
Create a reusable numeric projection from one numeric domain to another. Without a custom projector it performs a linear (lerp-based) remap that extrapolates past the bounds; pass `{ clamp: true }` to clamp the input to the `from` domain via the stdlib `remap`. The returned factory can be reused for many inputs.
Reactive logical `AND` across boolean refs or getters. The result is `true` only when every input resolves to a truthy value.
Reactive logical `NOT` of a boolean ref or getter. The result is `true` whenever the input resolves to a falsy value.
Reactively compute the logical `OR` across a list of boolean sources (each a ref, getter, or raw value). Returns a `ComputedRef<boolean>` that is `true` when at least one source is truthy. Short-circuits on the first truthy source, so later refs are only read when needed. With no arguments the result is `false` (the identity for `OR`). Fully SSR-safe — touches no globals.
A pure mapping from a value in the `from` domain to the `to` domain.
Reactive `Math.abs` of a number ref or getter
Reactively compute the average (arithmetic mean) of the provided numbers. Accepts either a variadic list of numbers (each a ref, getter, or raw value) or a single reactive array whose items may themselves be refs/getters. Returns `NaN` when there are no values, mirroring `0 / 0`.
Reactive `Math.ceil`. Rounds a number up to the next largest integer.
Clamps a value between a minimum and maximum value
Reactive `Math.floor`. Returns the largest integer less than or equal to the given value
Reactive wrapper over any callable `Math.<key>` method. Each argument may be a plain value, a ref or a getter; the result recomputes lazily whenever a reactive input changes.
Maps each argument of a `Math` method to a reactive equivalent (`MaybeRefOrGetter`), so callers may pass plain values, refs or getters.
Keys of `Math` that resolve to callable methods (excludes numeric constants such as `Math.PI` or `Math.E`).
Reactive result of the wrapped `Math` method.
Reactively compute the maximum of the provided numbers. Accepts either a variadic list of numbers (each a ref, getter, or raw value) or a single reactive array whose items may themselves be refs/getters.
Reactive `Math.min`. Accepts a variadic list of numbers (each a ref, getter, or plain value) or a single reactive array whose items may themselves be refs/getters.
Reactively set the decimal precision of a number.
Reactive numeric projection from one numeric domain to another. A thin one-shot wrapper over {@link createProjection}: it projects a single reactive `input` and returns a `ComputedRef` of the result. The default (lerp-based) projector extrapolates past the domain bounds; pass `{ clamp: true }` to clamp the input to the `from` domain. SSR-safe — it performs only pure arithmetic and touches no browser globals.
A reusable projection: given a reactive input it yields a `ComputedRef` of the projected value.
Reactive `Math.round` with optional decimal-place precision
Reactively compute the sum of the provided numbers. Accepts either a variadic list of numbers (each a ref, getter, or raw value) or a single reactive array whose items may themselves be refs/getters.
Reactive `Math.trunc`. Returns the integer part of a number by removing any fractional digits.
Media · 15
Subscribe to a media event hook; returns an unsubscribe handle.
Non-standard `performance.memory` heap statistics.
Reactive Web Bluetooth API. Prompts for a device and tracks its GATT server connection.
Reactive `mediaDevices.getDisplayMedia` (screen share) streaming.
Reactive controls and state for an `<audio>`/`<video>` element: play/pause, seeking, duration, buffered ranges, volume, mute, rate, text tracks, and Picture-in-Picture. Source and track injection are handled for you, and all DOM listeners attach passively with automatic cleanup. SSR-safe.
A media `<source>` descriptor injected as a child `<source>` element. Many of these definitions mirror MDN's HTMLMediaElement documentation.
A reactive snapshot of a single `TextTrack`.
A text track `<track>` descriptor injected as a child `<track>` element.
Reactive `performance.memory` heap statistics, polled on an interval. SSR-safe and a no-op where the API is unavailable.
Observe performance metrics via `PerformanceObserver`. The observer is (re)created only when activation changes, and can be paused, resumed, or permanently stopped. SSR-safe: nothing runs until mounted in a supporting environment.
Reactive wrapper around the Web Speech API `SpeechRecognition` for transcribing speech to text.
Reactive wrapper around the Web Speech `SpeechSynthesis` API for text-to-speech.
Reactive `navigator.mediaDevices.getUserMedia` streaming. Acquires a `MediaStream` for camera/microphone capture, keeps it in sync with reactive constraints, and auto-restarts on constraint changes while enabled. SSR-safe and race-safe — overlapping acquisitions never leave an orphaned stream open.
Simple Web Worker communication with reactive incoming data and automatic teardown
Run an expensive function in a transient Web Worker off the main thread
Reactivity · 29
Handle overlapping async evaluations. The provided callback is invoked when a re-evaluation of the computed value is triggered before the previous one finished, letting you abort stale work.
Default clone implementation. Prefers the structured clone algorithm and falls back to a JSON round-trip when `structuredClone` is unavailable (older runtimes / SSR) or the value is not structured-cloneable.
Computed value driven by an async (promise-returning) evaluation callback. The value updates reactively when its dependencies change, exposing an optional `evaluating` ref for pending state, an `onError` handler, lazy evaluation, and a default value used until the first resolution settles. Out-of-order resolutions are discarded so only the latest run wins, and an `onCancel` hook lets callbacks abort stale work.
Eager (non-lazy) computed value backed by a `watchEffect`-driven `shallowRef`. Unlike `computed`, the getter runs immediately and on every dependency change rather than lazily on read, so the cached value is always up to date. Best for cheap derived values that are read in many places.
A computed ref whose recomputation is driven only by an explicitly declared dependency `source`, plus a manual `.trigger()`. Built on `customRef` with a single `flush: 'sync'` watcher and a lazy `dirty` flag, so the getter is cached and only re-runs when the source changes or you trigger it — never on unrelated reactive reads. Also exposes `.peek()` (untracked read) and `.stop()` (detach the source watcher).
Attach extra (optionally reactive) attributes to a ref while keeping it a usable ref.
Computed that resolves to a reactive object whose individual fields stay reactive — read a single property and only that property is tracked, instead of the whole getter re-running on every access. The getter is wrapped in a single cached `computed`, so the object is recomputed only when one of its reactive dependencies changes. The returned value is a `reactive` proxy over that computed: destructuring with `toRefs`, spreading and writing back individual fields all work as on a normal `reactive` object.
Predicate deciding, per field, whether a key should be omitted. Return `true` to drop the field.
Resolved type of `reactiveOmit`: a reactive object that drops either the listed keys (`Omit`) or — when a predicate is used — an arbitrary subset (`Partial`), since the kept keys are only known at runtime.
Reactively pick a subset of keys (or keys matched by a predicate) from a reactive object. The result is a live `reactive` proxy: reads forward to the source's current value (so it tracks reassignment of nested refs) and writes pass straight back to the source. Unlike a `computed` of an object literal, no new object is allocated per recompute — the proxy is built once and lookups are resolved lazily on access.
Predicate form: receive each `(value, key)` pair of the source object and return `true` to keep the key in the resulting reactive view.
The reactive object produced by {@link reactivePick}: a subset of `T` restricted to the picked keys `K`, with each value unwrapped.
Create a ref that resets to its default value after a delay since the last write. Each set restarts the timer; reading is reactive.
A readonly ref whose value mirrors a source but only after updates stop arriving for `ms`. Wraps the source change in our debounce primitive (built on `debounceFilter`), so rapid bursts collapse into a single delayed write. Supports a `maxWait` ceiling so the value still progresses under sustained input, and tears its timer down with the owning scope.
Wrap a writable `ref` so that reads fall back to a default value whenever the source holds `null` or `undefined`, while writes pass straight through to the source. The default may itself be reactive (a ref, getter, or plain value), so the fallback can track other state. Implemented as a single writable `computed` — no watchers, no extra refs, nothing to tear down — which keeps it allocation-light and SSR-safe (it never touches the DOM).
A ref whose value updates are throttled. The returned ref mirrors the source but propagates changes at most once per `delay` window, making it useful for rate-limiting reactive updates driven by high-frequency events such as `scroll` or `resize`.
A ref with fine-grained control over its reactivity: read/write without tracking or triggering, plus `onBeforeChange` (vetoable) and `onChanged` hooks. Built on `customRef`, so there are no extra watchers.
Keeps two refs in sync (two-way by default, or one-way via `direction`), with optional value transforms.
Conversion functions used when the two refs hold different value types. - `ltr` maps a left value to a right value (used when the left ref changes). - `rtl` maps a right value to a left value (used when the right ref changes).
Convert a ref of object to a reactive proxy. Property reads and writes pass straight through to the ref's current value, so the proxy stays in sync even if the ref is reassigned to a whole new object. Writing a plain value onto a key that currently holds a ref unwraps into that ref's `.value`. Passing a plain object simply returns `reactive(object)`.
Caches the value of an external ref and updates it only when the value changes
Reactive deep clone of a source with a mutable cloned ref, modification tracking, and manual mode.
Debounce execution of a function — a thin reactive wrapper around `@robonen/stdlib`'s `debounce`. Postpones invocation until `ms` have elapsed since the last call and resolves with the wrapped function's result. Supports a reactive delay, a `maxWait` ceiling, `rejectOnCancel`, and exposes `cancel`, `flush`, and `isPending`. Pending timers are cleared on scope dispose.
Track the previous value of a ref, getter, or reactive source.
Syncs the value of a source ref with multiple target refs
Throttle execution of a function — a thin reactive wrapper around `@robonen/stdlib`'s `throttle`. Invokes `fn` at most once per `delay` window and resolves with the wrapped function's result. Especially useful for rate-limiting handlers on high-frequency events like `scroll` and `resize`. Accepts either positional arguments or a single options object, and exposes `cancel`/`flush` controls on the returned function.
Reactively convert a string or number ref to a number.
Reactively stringify a value, equivalent to `computed(() => String(toValue(value)))`.
Sensors · 50
The `BatteryManager` interface of the Battery Status API.
Subscribe to a gamepad lifecycle event. Returns a stop function that removes the listener; it is also auto-removed when the owning scope is disposed.
Decides whether the currently focused element already swallows text input (an `<input>`, `<textarea>`, or any `contenteditable` host). When it does we leave the keystroke alone so we never steal focus from a real text field.
Returns `true` when the event represents a single printable character typed without a command/control/alt modifier. Uses `KeyboardEvent.key` (a single Unicode grapheme for printable keys) instead of the deprecated `keyCode`, so it transparently covers digits, latin letters and any other printable glyph.
Maps a raw {@link Gamepad} into a named Xbox 360 controller layout (buttons, bumpers, triggers, sticks, dpad). Returns `null` while no gamepad is present.
Listen for `keydown` strokes. Shorthand for `onKeyStroke` with `eventName: 'keydown'`.
Listen for `keypress` strokes. Shorthand for `onKeyStroke` with `eventName: 'keypress'`.
Listen for keyboard strokes. Accepts a key, list of keys, or a predicate and fires the handler for matching events. Auto-cleans up on scope dispose. Overload 1: Explicit key filter
Listen for `keyup` strokes. Shorthand for `onKeyStroke` with `eventName: 'keyup'`.
Directive-like helper that invokes a handler after a sustained long press on a target element. Movement beyond `distanceThreshold` cancels the press, and an optional `onMouseUp` callback reports the press duration, distance, and long-press status. Listeners are passive by default and registered via `useEventListener` for automatic cleanup.
Fires the callback when the user starts typing on a non-editable element, ideal for auto-focusing a search box.
Adjusts a normalised (`-0.5 ~ 0.5`) parallax value before it is returned.
Where the parallax `roll`/`tilt` values are currently being derived from.
Subset of the `ScreenOrientation` interface that we interact with.
Reactive Battery Status API. Tracks the device charging state, charge level, and the estimated charging/discharging times, keeping them in sync with the underlying `BatteryManager` events.
Reference-counted body scroll lock. Safe to invoke from multiple concurrent modals — the lock releases only after all holders release. Preserves the original overflow/padding/touch-action values and compensates for scrollbar removal to prevent layout shift.
Invokes `handler` when a pointer event occurs outside `target`. SSR-safe: no-op on the server. Handles portaled/ignored subtrees and guards against synthetic "outside" clicks on removed nodes.
Reactive `DeviceMotionEvent` exposing acceleration (with and without gravity), rotation rate, and the hardware sampling interval. SSR-safe, uses a single passive listener, and supports the iOS 13+ permission flow.
Reactive [`DeviceOrientationEvent`](https://developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent). Provides physical orientation of the device relative to Earth's coordinate frame.
Reactively track `window.devicePixelRatio`, updated via a `matchMedia(resolution)` listener (fires on zoom and on monitor changes).
Reactive `enumerateDevices` listing available media input/output devices.
Reactive element(s) at a given viewport point, sampled every animation frame via `document.elementFromPoint` (or `elementsFromPoint` when `multiple` is set).
Reactive hover state of an element, driven by `mouseenter` / `mouseleave`. Supports independent enter/leave delays to debounce flicker.
Register a callback for the topmost Escape keydown. Uses an internal stack so that nested layers (e.g. nested Dialogs) dismiss in the correct order — only the most recently-registered listener fires for a given keydown.
Reactive focus state of an element. The returned `focused` ref tracks focus/blur events and can be written to in order to focus or blur the target.
Reactive tracking of whether an element or any of its descendants are focused, backed by the `focusin`/`focusout` events.
Reactive FPS counter based on `requestAnimationFrame`. Reports a smoothed FPS value averaged over a configurable number of frames, and tracks min/max values.
Reactive wrapper around the Gamepad API. Tracks connected gamepads, emits connection/disconnection events, and polls live button/axis state on every animation frame. The polling loop stays paused while no gamepad is connected and resumes automatically on the first connection, so there is zero idle work. SSR-safe.
Reactive Geolocation API. Watches the device position, exposing reactive coordinates, error, and readiness state, plus pause/resume controls and a one-shot `getCurrentPosition`.
Track whether the user has been inactive for a given duration.
Trigger a loader as a scroll container nears one of its edges. Backed by {@link useScroll} for RTL-aware arrived-edge detection: the `distance` is folded into that direction's offset, so `onLoadMore` fires the moment the edge comes within `distance` pixels. Re-checks automatically after each load (so an under-filled container keeps loading) and degrades safely under SSR and when `IntersectionObserver` is unavailable.
Result of the `onLoadMore` callback. May be synchronous or a promise; the loader is considered busy until it settles.
Reactive state of a keyboard modifier (CapsLock, NumLock, Shift, Control, Alt, Meta, ...) tracked via `KeyboardEvent.getModifierState`.
Reactive keys pressed state, with magical combination keys support via a Proxy. Access combinations directly as properties, e.g. `keys['ctrl+a']` or `keys.ctrl_a`.
Reactive mouse (and optionally touch) position with optional custom target, scroll tracking, custom extractors, and event filtering.
Extracts an `[x, y]` pair from a mouse or touch point, or `null` to skip.
Reactive mouse position relative to an element. Exposes the cursor position, the cursor position relative to the element's top-left corner, the element's position and size, and whether the cursor is outside the element. Element geometry is observed via `useElementBounding` (`ResizeObserver` + `MutationObserver` + window scroll/resize), so the relative coordinates stay correct as the element moves or resizes — without re-measuring the element on every pointer move.
Reactive mouse/touch/drag pressed state on a target, with the input source type and optional press/release callbacks.
Reactive Network Information API state plus online/offline status.
Reactive online/offline status based on `navigator.onLine`. For connection details (effectiveType, downlink, saveData, transition timestamps, ...) use {@link useNetwork} instead.
Reactive flag indicating whether the mouse has left the page.
Reactive parallax effect. Prefers the device orientation sensors and transparently falls back to mouse position when orientation is unavailable. Composes {@link useDeviceOrientation} and {@link useMouse}; pass a `target` to make the mouse fallback relative to an element's centre instead of the whole viewport. SSR-safe.
Reactive pointer state (position, pressure, tilt, size, and pointer type) sourced from pointer events on a target, plus whether the pointer is currently inside it.
Reactive [Pointer Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API). Locks the mouse cursor to an element and tracks the locked element reactively.
Detect swipe gestures via PointerEvents on a target element. Works for mouse, touch and pen with a single unified event model, tracking start/end coordinates, the active state and the resolved direction.
Reactive Screen Orientation API. Tracks the current orientation `type` and `angle`, and exposes helpers to lock/unlock the orientation. SSR-safe.
Reactive scroll position and state for an element or the window, with arrived-edge detection (RTL-aware), scroll directions, an `isScrolling` flag, optional throttling, and a `measure()` method for manual re-sync.
Lock scrolling of an element by toggling `overflow: hidden`, preserving the element's prior inline overflow and handling iOS `touchmove`. Returns a writable boolean ref — set it to lock/unlock, read it for state.
Detect swipe gestures via touch events on a target element. Tracks start/end coordinates, the active state and the resolved direction.
Reactively track the user's text selection via `Window.getSelection`.
State · 16
Promotes a composable to a shared one: every call reuses the same instance backed by a single effect scope. The scope is created lazily on the first consumer and is ref-counted, so it is disposed only when the last consumer's scope unmounts. State is recreated on the next call after a full dispose.
Provides a shared state object for use across Vue instances
A composable that provides a state for async operations without setup blocking
A composable that provides a factory for creating context with unique key
A composable that provides a counter with increment, decrement, set, get, and reset functions
Cycle through a list of items, with `next`/`prev`/`shift`/`go` controls. Supports a reactive list — the index is kept valid when the list changes.
Track the change history of a ref, debouncing commits so that rapid bursts of changes collapse into a single history record. A shorthand for {@link useRefHistory} pre-wired with a debounce {@link EventFilter}.
SSR-safe unique identifier. Thin wrapper around Vue 3.5's built-in `useId()` that accepts an optional prefix and allows callers to pass a pre-existing id (useful for primitives that accept a user-supplied `id` prop).
Create a global state that can be injected into components
Records the last time a value changed
Manually-committed undo/redo history for a ref. Records snapshots only when `commit()` is called, with optional cloning, serialization, and a bounded capacity.
A composable function that provides pagination functionality for offset based pagination
Track the change history of a ref with undo/redo, pause/resume, batching, and manual commits.
A composable for building wizards/steppers over a list or record of steps
Shorthand for {@link useRefHistory} with a throttled event filter, so rapid source changes are committed at most once per interval (trailing edge by default).
A composable that provides a boolean toggle with customizable truthy/falsy values
Storage · 6
Reactive localStorage binding — creates a ref synced with `window.localStorage`
Reactive sessionStorage binding — creates a ref synced with `window.sessionStorage`
Reactive Storage binding — creates a ref synced with a storage backend
Reactive Storage binding with async support — creates a ref synced with an async storage backend
Types · 14
Argument form accepted by the reactive math helpers (`useMax`, `useMin`, `useSum`, `useAverage`): either a spread of (possibly reactive) values, or a single (possibly reactive) array of them.
A ref that can be set to `null` to remove the associated storage entry. Setting the value to `null` or `undefined` will call `removeItem` on the storage backend.
The actions for a resumable process.
Often times, we want to pause and resume a process. This is a common pattern in reactive programming. This interface defines the options and actions for a resumable process.
A failed validation result.
Infer the input type of a Standard Schema.
Infer the output type of a Standard Schema.
A single validation issue.
A single segment of an issue path.
The properties carried on a schema's `~standard` key.
The result of validating a value: either a success carrying the typed output or a failure carrying a list of issues.
A successful validation result.
The inferred input/output types of a schema.
Vendored, dependency-free types for the [Standard Schema](https://github.com/standard-schema/standard-schema) spec (v1). Any validation library implementing the `~standard` contract — zod, valibot, arktype, … — is structurally assignable to {@link StandardSchemaV1}, so the forms layer can accept them without taking on a dependency. The namespace pattern from the official spec is flattened into named exports to stay within the repo's lint rules.
Utilities · 17
Lightweight, non-reactive event hook factory exposing `{ on, off, trigger, clear }`. `on` returns a callable off handle (also carrying an `.off` method) and auto-removes the listener on scope dispose. `trigger` awaits async listeners and resolves with all their results. SSR-safe (touches no browser globals) and tree-shakeable.
Anything usable to identify a shared bus. Buses with an equal identifier share their listener set, regardless of how many times `useEventBus` runs.
A branded `Symbol` that carries the bus' event type so a typed key can be shared across modules without re-declaring generics at every call site.
A listener invoked when its bus emits. Receives the emitted `event` value and an optional `payload`.
A listener for an event hook. `T` is the payload type: - `void` -> the listener takes no arguments - a tuple `[a, b]` -> the listener takes those positional arguments - anything else -> the listener takes a single argument of that type Listeners may be sync or async; async listeners are awaited by `trigger`.
Handle returned from {@link EventHook.on}. It is both a callable that removes the listener and an object exposing an `off` method, so either of these work: ```ts const off = on(fn); off(); const { off } = on(fn); off(); ```
Shorthand accessor that unwraps a ref/getter to its value, optionally reading a single property off the resolved value. Accepts plain values, refs and getter functions (via `toValue`), so it works anywhere `unref`/`toValue` would. Purely synchronous and side-effect free, so it is fully SSR-safe.
Type-guard that checks whether a ref's (or plain value's) current value is neither `null` nor `undefined`, narrowing the source to its `NonNullable` form. Unwraps refs with a single `unref` — no extra reactivity or watchers are created, so it is a cheap synchronous check that is fully SSR-safe. For a reactive guard that tracks changes, use {@link useIsDefined}.
The result of {@link isDefined}: a plain boolean acting as a type guard.
The type of the key used to index the cache. Defaults to a serialized string but may be any value when a custom `getKey` is supplied.
Shorthand setter that mirrors {@link get}. Either assigns `value` to a ref (`ref.value = value`) or assigns `value` to a single property of an object (`target[key] = value`). The arity is resolved at the type level via overloads, so both forms stay fully type-safe. Purely synchronous and side-effect free, so it is fully SSR-safe.
A typed, SSR-safe event bus. Calls sharing an identifier share listeners, giving cross-component (and cross-module) communication without prop drilling or provide/inject. Backed by stdlib `PubSub` for stable snapshot-based emit semantics, and auto-removes the current scope's listeners on dispose so components never leak subscriptions.
Reactive counterpart to {@link isDefined}. Returns a `ComputedRef<boolean>` that re-evaluates whenever the source ref, getter, or plain value resolves to a non-nullish value. Use this when the definedness itself needs to drive reactivity (templates, watchers, derived state); reach for the synchronous {@link isDefined} when you only need a one-off type guard.
The result of {@link useIsDefined}: a readonly computed boolean.
Cache the result of a (possibly async) function by its arguments, exposing a reactive cache and explicit `load`/`delete`/`clear`/`generateKey` controls. When no custom `cache` is supplied the default `Map` path delegates to `@robonen/stdlib`'s `memoize` for the get-or-compute core and is wrapped in `shallowReactive` so cache reads inside effects stay live. A custom cache backend (e.g. an LRU) can be plugged in via `options.cache`. SSR-safe: no browser globals are touched.
Pluggable cache backend. Any object implementing this shape can be supplied via `options.cache` to control storage (e.g. an LRU cache). When omitted a plain `Map` is used and the heavy lifting is delegated to `@robonen/stdlib`'s `memoize`.
SSR-friendly way to check if a feature is supported
Utils · 6
Wrap a function with an {@link EventFilter}, preserving arguments, `this`, and the return value through a promise. The wrapper returns a promise that resolves with the result of the wrapped function once the filter lets it through. When the filter coalesces calls (e.g. debounce/throttle), every pending promise scheduled since the last invocation resolves together with that invocation's result — so nothing is left dangling.
Create a debounce event filter — a reactive-aware wrapper around `@robonen/stdlib`'s `debounce` (trailing edge).
Function to get the target instance of the lifecycle hook
Create a pausable event filter When paused, invocations are queued and replayed on resume.
Create a throttle event filter — a reactive-aware wrapper around `@robonen/stdlib`'s `throttle`.
VueToolsError is a custom error class that represents an error in Vue Tools
Watch · 7
Promised one-time watch for ref / getter changes. Resolve once the source matches a condition, optionally with a timeout.
Debounced `watch`. The callback is postponed until `debounce` milliseconds have elapsed since the last source change; an optional `maxWait` caps how long it can be delayed under sustained changes. Implemented via an event filter so the public surface matches `watch` exactly.
Extended `watch` that exposes `ignoreUpdates(fn)` and `ignorePrevAsyncUpdates()` to suppress reactions to programmatic writes.
Shorthand for `watch` that automatically stops after the callback fires once.
A `watch` whose execution can be paused and resumed on demand via a pausable event filter.
Like `watch`, but throttles the callback so it fires at most once per interval.
Shorthand for watching a source to be truthy. Behaves like `watch`, but the callback only fires when the resolved value is truthy.