Create a library-grade Vue composable that accepts maybe-reactive inputs (MaybeRef / MaybeRefOrGetter) so callers can pass a plain value, ref, or getter.
All-time #1340Trending #3960First seen Jan 28, 2026
Create a library-grade Vue composable that accepts maybe-reactive inputs (MaybeRef / MaybeRefOrGetter) so callers can pass a plain value, ref, or getter.
Normalize inputs with toValue()/toRef() inside reactive effects (watch/watchEffect) to keep behavior predictable and reactive.
Use this skill when user asks for creating adaptable or reusable composables.
Similar popular skills
Related neighbors and high-traction skills in the same topics — useful to compare before installing.
Files included with this skill beyond the listing page.
skill mdSKILL.md2,672 B
docsSUMMARY.md393 B
History
First seen on skills.sh
First recorded snapshot · 11,917 installs
SKILL.md
Create Adaptable Composable
Adaptable composables are reusable functions that can accept both reactive and non-reactive inputs. This allows developers to use the composable in a variety of contexts without worrying about the reactivity of the inputs.
Steps to design an adaptable composable in Vue.js:
Confirm the composable's purpose and API design and expected inputs/outputs.
Identify inputs params that should be reactive (MaybeRef / MaybeRefOrGetter).
Use toValue() or toRef() to normalize inputs inside reactive effects.
Implement the core logic of the composable using Vue's reactivity APIs.
Core Type Concepts
Type Utilities
/**
* value or writable ref (value/ref/shallowRef/writable computed)
*/
export type MaybeRef<T = any> = T | Ref<T> | ShallowRef<T> | WritableComputedRef<T>;
/**
* MaybeRef<T> + ComputedRef<T> + () => T
*/
export type MaybeRefOrGetter<T = any> = MaybeRef<T> | ComputedRef<T> | (() => T);
Policy and Rules
Read-only, computed-friendly input: use MaybeRefOrGetter
Needs to be writable / two-way input: use MaybeRef
Parameter might be a function value (callback/predicate/comparator): do not use MaybeRefOrGetter, or you may accidentally invoke it as a getter.
DOM/Element targets: if you want computed/derived targets, use MaybeRefOrGetter.
When MaybeRefOrGetter or MaybeRef is used:
resolve reactive value using toRef() (e.g. watcher source)
resolve non-reactive value using toValue()
Examples
Adaptable useDocumentTitle Composable: read-only title parameter
import { watch, toRef } from 'vue'
import type { MaybeRefOrGetter } from 'vue'
export function useDocumentTitle(title: MaybeRefOrGetter<string>) {
watch(toRef(title), (t) => {
document.title = t
}, { immediate: true })
}