Use when choosing or implementing reactive composables in STX, data queries, forms, consent, browser APIs, motion, or debugging client delivery. Covers @stacksjs/composables, STX eager and demand browser delivery, and the difference between callable signals and module Refs.
Resources
1Install
npx skillscat add stacksjs/stacks/stacks-composables Install via the SkillsCat registry.
Stacks composables
Choose the execution surface before copying a composable signature. An STX
client script, an explicitly imported @stacksjs/composables module, and a
server script can expose similarly named functions with different contracts.
Read BROWSER.md for template delivery, forms and motion examples.
Eager window aliases
The following markers describe only explicit eager window.name aliases ingetCachedSignalsRuntime(). They are checked bycore/composables/tests/skill-runtime-globals.test.ts, and are not the whole
compiler-delivered client surface.
useAsync, useClickOutside, useColorMode, useCounter, useDark,useDebounce, useDebouncedValue, useEventListener, useFetch, useFocus,useHead, useInterval, useLocalStorage, useMutation, useQuery,useRef, useRoute, useSearchParams, useSeoMeta, useSessionStorage,useStore, useThrottle, useTimeout, useToggle, useWebSocket.
Additional STX names are exposed through window.stx and compiler
destructuring, or bundled from STX composables on demand. In current STX,useMediaQuery and usePreferredReducedMotion use the first path;useForm, useScroll, useMouse, useParallax, anduseIntersectionObserver use the demand path. These client-script names do
not come from the ambient browser-auto-imports.json manifest.
Explicit module imports
The module surface lives in core/composables/src/index.ts. Import every
binding in a TypeScript module even if a template entry can use it bare.
import { useCounter } from '@stacksjs/composables'
const counter = useCounter(0, { min: 0, max: 10 })
counter.inc()
const value = counter.count.valueModule composables use object Ref values from STX: read/write .value,
subscribe where provided, and use the exported cleanup/control functions.
Template signals use count(), .set(), and .update(). Passing a callable
signal into a module helper expecting a Ref is not an implicit conversion.
| Task | Explicit module exports |
|---|---|
| State/storage | useCounter, useToggle, useStorage, useLocalStorage, history helpers |
| Async/data | useFetch, createFetch, useQuery, useMutation, createQueryClient, useAsyncState |
| Forms/consent | useForm, useCookieConsent |
| DOM/input | useFocus, useEventListener, onClickOutside, observers, useScroll, useMouse |
| Timing/watch | useIntervalFn, useTimeoutFn, useTimeoutPoll, watchDebounced, watchPausable |
| Media/device | useMediaQuery, usePreferredReducedMotion, useGeolocation, useDeviceOrientation |
| Browser facilities | clipboard, permissions, fullscreen, workers, virtual lists, sharing |
Inspect the barrel and the individual implementation for other exports rather
than installing a second library for a feature Stacks already has.
Module query cache
useQuery({ queryKey, queryFn, staleTime, enabled, client }) provides Ref
data/error/loading state, in-flight deduplication and refetch().queryFn receives an AbortSignal. createQueryClient({ gcTime }) provides
scoped clients, get, set, invalidate, gc, and clear.
Invalidation accepts prefix keys or a predicate matcher. OptionalrefetchOnFocus and refetchOnReconnect refetch stale data. Useunsubscribe() when the consumer ends. For template runtime queries read
the STX contract in BROWSER.md; their signatures differ.
Module forms and consent
Explicit useForm({ initialValues, schema, onSubmit, validateOn }) accepts
Stacks validators, exposes Ref values plus field(name) accessors, dirty/touched
state, accessible inputProps(), submitButtonProps(), and server-errorsetErrors(). Apply a returned 422 map explicitly; fetching an error does
not automatically attach it to a form. Field arrays and a progressive HTML
fallback are not established by the primitive alone.
useCookieConsent({ policyVersion, storageKey, onChange }) stores a versioned
decision. Necessary consent is always enabled; optional categories default to
declined. accept, acceptAll, declineAll, and withdraw change it;allows(category) gates loading. A changed policy version asks again, blocked
storage falls back to no stored decision, and returned visitor consent is
independent of a signed-in session. Import this helper explicitly.
Gotchas
- Browser capability availability and permission denial are runtime states,
even when a helper imports successfully during SSR. - Client observers/listeners need teardown. Read the selected helper's return
shape;stop,remove, andunsubscribeare not interchangeable names. - Module
useTimeout(ms)returns a Ref unless controls are requested; browser
runtimeuseTimeout(callback, delay)runs a callback. Module counter methods
areinc/dec, neverincrement/decrement. - Typechecking an ambient name proves neither its delivery nor its contract.
Exercise a rendered template with the installed STX version.
Source and evidence
core/composables/src/index.ts, individual source files, and retainedtests/use-query.test.ts, tests/use-form.test.ts,tests/use-cookie-consent.test.ts and tests/skill-runtime-globals.test.ts
are authoritative (core paths relative to storage/framework/).