Skip to main content
skill Claude Code CX Codex Cursor GitHub Copilot

create-adaptable-composable — Claude Code skill: flexible Vue

Skill for writing reusable Vue composables that accept values, refs, or getters and work the same way in all cases. Use it when you need a library-grade composable that adapts to different input types.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add vuejs-ai/skills --skill create-adaptable-composable -a claude-code
Open on GitHub

What create-adaptable-composable does

The skill teaches how to write composables that accept MaybeRef or MaybeRefOrGetter — types letting callers pass a plain value, ref, computed, or function-getter. Inside the composable, you use toValue() to read a value and toRef() to create a reactive source, so the logic behaves predictably in watch or watchEffect.

The skill outlines four steps: confirm the composable's purpose and API, identify which parameters should be reactive, normalize inputs with toValue()/toRef() inside effects, implement the core logic. The rule: use MaybeRefOrGetter for read-only parameters, MaybeRef for writable ones. Don't use MaybeRefOrGetter for callbacks or predicates — you might accidentally invoke them as getters.

Requires Vue 3 or Nuxt 3. The repository includes examples: useDocumentTitle watches a title with toRef, useCounter modifies count through toRef and returns an add function.

What it helps with

  • write a composable that accepts a value, ref, or getter without extra checks
  • make a reactive parameter that doesn't break when input type changes
  • pick between MaybeRef and MaybeRefOrGetter based on use case
  • normalize inputs in watch and watchEffect without losing reactivity
  • build a reusable composable for a library

Example prompts for the agent

  • Help me write useCounter composable that accepts MaybeRef for count and returns an add function
  • Create an adaptable composable to track screen width, accepting MaybeRefOrGetter for selector
  • I need a composable with a two-way form parameter — use MaybeRef and toRef inside watch

How to install create-adaptable-composable

1Skills CLI (Vercel)

npx skills add vuejs-ai/skills --skill create-adaptable-composable -a claude-code

2Manually: put the files in place

~/.claude/skills/create-adaptable-composable/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/create-adaptable-composable/

From the same set7

The whole set →
vue-best-practices github.com/vuejs-ai Enforces Vue 3 guidelines using Composition API and TypeScript. Helpful for structuring SFCs, managing reactivity, and writing composables. Claude Code CX Codex Cursor +1 42,700installs vue-debug-guides github.com/vuejs-ai Skill for diagnosing Vue 3 errors: reactivity, watchers, components, templates, and hydration. When the agent sees a Vue bug, it looks up the cause in a catalog of common issues. Claude Code CX Codex Cursor +1 26,700installs vue-pinia-best-practices github.com/vuejs-ai A skill covering Pinia best practices: avoid common store setup errors, preserve reactivity, and organize state management patterns in Vue projects. Claude Code CX Codex Cursor +1 16,800installs vue-router-best-practices github.com/vuejs-ai Skill teaches AI coders Vue Router 4 patterns: navigation guards, route params handling, and component lifecycle synchronization. Prevents infinite redirects, memory leaks, and data desync. Claude Code CX Codex Cursor +1 14,900installs vue-testing-best-practices github.com/vuejs-ai Skill offering Vue 3 testing patterns and best practices. It helps configure Vitest and write blackbox component tests without brittle assertions. Claude Code CX Codex Cursor +1 13,600installs vue-options-api-best-practices github.com/vuejs-ai Guidance for Vue 3 Options API components, covering TypeScript, method context, and lifecycle hook pitfalls. Useful when reviewing or writing Options API code. Claude Code CX Codex Cursor +1 11,600installs

Similar

build-zoom-meeting-sdk-app official anthropics Reference skill for embedding Zoom Meeting SDK across web and mobile applications. Guides client embeds and backend auth flows. Claude Code CX Codex Cursor +1 2,100installs impeccable-design-polish nexu-io Polishes existing HTML pages by removing generic AI styling cues, fixing mobile layout bugs, and tightening accessibility. Claude Code CX Codex Cursor +1 2,500installs threejs-shaders CloudAI-X Guides the agent through writing GLSL shaders, custom materials, and TSL nodes for Three.js r186 across WebGL and WebGPU. Claude Code CX Codex Cursor +1 15,400installs material-ui-theming mui Skill for building and managing Material UI themes: palettes, color schemes, CSS variables, light/dark switching, and TypeScript augmentation. Use it when designing your app's visual system or implementing theme customization. Claude Code CX Codex Cursor +1 604installs zoom-apps-sdk official anthropics Reference skill for the Zoom Apps SDK. Gives your agent the API surface for web apps running inside Zoom meetings, webinars, the main client, and Zoom Phone. Claude Code CX Codex Cursor +1 2,000installs frontend-design official anthropics This skill guides intentional visual design for new interfaces and redesigns. Use it when a generic generated UI is not enough. Claude Code Claude.ai 1,025,790installs design-taste-frontend Leonxlnx This skill directs the design of public pages and work screens, then checks the result in a browser through screenshots. Use it when an interface feels generic or unfinished. Claude Code CX Codex Cursor +1 673,100installs prototype Matt Pocock Creates throwaway prototypes for checking state logic or exploring UI before committing the decision to the main codebase. Claude Code 986,201installs

Questions about create-adaptable-composable

How do I install create-adaptable-composable in Claude Code?

Run npx skills add vuejs-ai/skills --skill create-adaptable-composable -a claude-code, then open ~/.claude/skills/create-adaptable-composable/SKILL.md.

What's the difference between MaybeRef and MaybeRefOrGetter?

MaybeRef is for parameters you need to modify (ref, computed, value). MaybeRefOrGetter adds getter functions, fit for read-only sources like selectors. If the parameter is a callback, don't use MaybeRefOrGetter — you'd accidentally invoke the function.

When should I use this skill?

When writing composables for libraries or components that other developers will use with different input types — values, refs, computed, or getters. The skill ensures your composable works in all cases.

Source text

SKILL.md · MIT
---
name: create-adaptable-composable
description: 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.
license: MIT
metadata:
  author: github.com/vuejs-ai
  version: "17.0.0"
compatibility: Requires Vue 3 (or above) or Nuxt 3 (or above) project
---

# 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:
1. Confirm the composable's purpose and API design and expected inputs/outputs.
2. Identify inputs params that should be reactive (MaybeRef / MaybeRefOrGetter).
3. Use `toValue()` or `toRef()` to normalize inputs inside reactive effects.
4. Implement the core logic of the composable using Vue's reactivity APIs.

## Core Type Concepts

### Type Utilities

```ts
/**
 * 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

```ts
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 })
}
```

Adaptable `useCounter` Composable: two-way writable count parameter

```ts
import { watch, toRef } from 'vue'
import type { MaybeRef } from 'vue'

function useCounter(count: MaybeRef<number>) {
  const countRef = toRef(count)
  function add() {
    countRef.value++
  }
  return { add }
}
```

© github.com/vuejs-ai · MIT · vuejs-ai/skills

See also

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor