← Back to Website builders
See how it helps
2. Flexible inputs with
Reusable Vue behavior
Extracts repeated reactive behavior into focused functions with clear inputs, explicit actions and automatic resource cleanup.
vue-composables
Team members using this skill
When is it useful?
Use when several Vue components duplicate fetching, keyboard handling or subscriptions, making fixes difficult to apply consistently.
What does it help you do?
- Checks existing utilities before extracting a new composable with one responsibility.
- Accepts reactive inputs and exposes understandable state and action contracts.
- Releases listeners, timers and pending requests when their owner disappears, including server-rendering considerations.
Try asking this
Extract our repeated search logic into a composable. It should accept changing filters, expose loading and refresh actions, and cancel its request when the component closes. Use the composable in two independent search panels. Closing one must cancel only its request, while changing reactive filters starts a fresh query without stale results.
Detailed documentation
Read the skill’s original instructions, examples and checks in their authored language.
Show less
Composable Design
Build focused, composable use* functions that hide real stateful or side-effect complexity behind a small, predictable TypeScript interface.
1. When to write a composable (and when not to)
- Check existing project composables and
@vueuse/core(if installed) before writing a new one. - Extract a composable when stateful reactive logic or side effects (event listeners, observers, async resource lifecycles, keyboard shortcuts, synced storage) are reused across components or obscure a component's main flow.
- Keep stateless, pure transformations in plain TypeScript utility functions (
formatCurrency,parseQuery), notuse*composables. - Give each composable one clear responsibility (
useDocumentTitle,useDebouncedSearch,usePagination) instead of a monolithicusePageEverything.
2. Flexible inputs with MaybeRefOrGetter
- Accept reactive and plain inputs seamlessly using Vue 3.3+ types:
- Read-only inputs: type as
MaybeRefOrGetter<T>and normalize insidecomputed,watchor effects withtoValue(input). - Mutable ref inputs: type as
MaybeRef<T>and normalize withtoRef(input).
- Read-only inputs: type as
- Take 1–2 required positional arguments and group optional configuration into a typed
options?: UseFeatureOptionsobject with sensible defaults.
3. Return contract and encapsulation
- Return a plain object of refs and functions (
return { items: readonly(items), isLoading: readonly(isLoading), refresh }) so callers can destructure properties without losing reactivity, while still allowing reactive wrapping if needed. - Wrap internal state refs in
readonly()when external callers should only mutate state through the composable's returned actions. - Make side effects and async triggers explicit: document or configure via
immediate?: booleanwhether an async composable fetches on creation or waits for an explicit action call.
4. Lifecycle, cleanup and SSR safety
- Call
onMounted,onUnmounted,onScopeDisposeandinjectsynchronously at the top of the composable before anyawait. - Use
getCurrentScope()+onScopeDispose(cleanup)(oronUnmounted) to release timers,AbortControllers, DOM listeners and subscriptions automatically when the owning component oreffectScopestops. - Guard browser-only globals (
window,document,localStorage,matchMedia) behindonMountedortypeof window !== 'undefined'checks so the composable never crashes during SSR or unit tests. - Never store per-request mutable state at module scope unless the composable is an intentional client-only singleton (and even then, prefer Pinia or
createSharedComposablewhen SSR is not used).
Before you finish
- Existing composables and
@vueuse/corechecked before creating a new one. - Inputs accept
MaybeRefOrGetter<T>normalized viatoValue()where reactivity is useful. - Returns a plain object of refs (with
readonly()on internal state) and explicit action functions. - Listeners, timers and in-flight requests are cleaned up via
onScopeDispose/onUnmounted/onWatcherCleanup.
Included files 2
LICENSE.txtSKILL.md
