Vue 3 Composition API discipline: reactivity-aware, type-safe, composable. Invoke whenever task involves any interaction with Vue code — writing, reviewing, refactoring, debugging, or understanding .vue files, composables, and Vue component architecture.
Guides Vue 3 development with Composition API best practices for writing, reviewing, and refactoring components.
npx claudepluginhub xobotyi/cc-foundryThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/components.mdreferences/composables.mdreferences/performance.mdreferences/reactivity.mdreferences/sfc.mdreferences/typescript.mdComposition API is the default. <script setup> is the default syntax.
If you reach for Options API, you need a reason.
Vue 3 rewards explicit, composable code. Prefer ref() over reactive(),
composables over mixins, and typed props over runtime-only validation.
References contain extended examples, rationale, and edge cases for each topic.
| Topic | Reference | Contents |
|---|---|---|
| Reactivity | references/reactivity.md | Ref unwrapping, watchers, computed edge cases |
| SFC | references/sfc.md | Full compiler macros catalog, scoped styles, template refs |
| Components | references/components.md | Props, emits, slots, provide/inject |
| Composables | references/composables.md | Design patterns, composition, restrictions |
| TypeScript | references/typescript.md | Full utility types table, generic components, event typing |
| Performance | references/performance.md | Update optimization, large lists, profiling |
| Primitive | Use when |
|---|---|
ref() | Default choice. Works with any value type. |
reactive() | Grouping related state when destructure is not needed. |
shallowRef() | Large immutable structures, external state integration. |
shallowReactive() | Root-level-only reactivity on objects. |
computed() | Derived state. Caches until dependencies change. |
ref() Is the Primary APIstring, number, boolean).count.value = newValue)..value access pattern everywhere in script..value in script, omit in template — templates auto-unwrap top-level refs.reactive() Limitationsstate = reactive({...}) breaks tracking.toRefs() if you must destructure.reactive() as the primary primitive. Use ref().{{ count }} works.{{ obj.id + 1 }} breaks
if obj.id is a ref. Destructure to top level to fix.reactive() objects are unwrapped automatically..value.get/set form.watch() vs watchEffect():
Use watch() when | Use watchEffect() when |
|---|---|
| Need old and new values | Don't need old value |
| Want lazy execution | Want immediate execution |
| Watching specific sources | Dependencies are implicit |
| Need conditional watching | Effect tracks all accessed refs |
watch() options:
{ immediate: true } — run callback on creation (like watchEffect).{ deep: true } — watch all nested properties (expensive, use sparingly).watch(() => obj.specificProp, callback).watch([a, b], ([newA, newB]) => {...}).Cleanup: Both watch and watchEffect support cleanup via the onCleanup parameter.
Use it for aborting fetch requests, clearing timers, removing listeners.
Reactive state changes batch DOM updates to the next tick. Use nextTick() for
post-DOM-update logic.
Always: <script setup> first, <template> second, <style> last.
<script setup>Order declarations logically:
defineProps, defineEmitsuseRouter(), custom composablesref(), reactive(), computed()watch(), watchEffect()onMounted(), onUnmounted()defineExpose() (rare)Key macros available without import in <script setup>: defineProps(),
defineEmits(), defineModel(). Use defineOptions() for options that
<script setup> doesn't natively support (name, inheritAttrs: false).
Full macro catalog in references/sfc.md.
Directive shorthands — use consistently, don't mix:
| Shorthand | Full | Purpose |
|---|---|---|
:prop | v-bind:prop | Bind attribute/prop |
@event | v-on:event | Listen to event |
#slot | v-slot:slot | Named slot |
Conditional rendering:
v-if / v-else-if / v-else for conditional blocks.v-show for frequent toggles (CSS display: none, avoids mount/unmount cost).v-if for conditions that rarely change, v-show for frequent toggles.Template refs:
useTemplateRef<HTMLInputElement>('input') with matching ref attribute.ref<HTMLInputElement | null>(null) with matching ref name.<style scoped> by default. Global styles only in App.vue or layouts..parent :deep(.child-class) to style child internals (use sparingly).<style module> generates unique class names, accessed via $style.v-bind(color) in <style> uses reactive values in CSS.TodoItem not Item. Avoids HTML element conflicts.<TodoItem />. Kebab-case only in in-DOM templates.TodoItem.vue.BaseButton, BaseIcon.TodoListItem, TodoListItemButton.SearchButtonClear, SearchInputQuery.<MyComponent />.defineProps<T>() (type-based) in TypeScript projects. Object syntax in JS
projects. Never array syntax in committed code.camelCase, use in templates as kebab-case — Vue converts automatically.computed() for transformations, ref() + initial value
for local copies.useComposable(() => id).defineEmits() — preferably type-based.camelCase: emit('someEvent'). Listen in kebab-case:
@some-event="handler". Vue converts automatically.defineEmits<{ change: [id: number] }>().defineModel<T>() for two-way binding shorthand.defineModel<string>('firstName') with
v-model:first-name="first" on parent.<slot /> in child, content between tags in parent.<slot name="header" /> in child, <template #header> in parent.<slot :item="item" />, consume with
<template #default="{ item }">.Symbol keys (InjectionKey<T>) for type safety — avoid string collisions.keys.ts file.readonly() refs to prevent consumers from mutating state.undefined in the consumer.v-for always has :key — stable, unique identifiers.v-if on same element as v-for. Use computed to filter, or wrap with
<template v-for>.computed or functions.use: useMouse, useFetch, useAuth.camelCase naming: useEventListener not use-event-listener.use prefix signals the function uses Vue reactivity and must be called
within setup() or <script setup>.Follow this order: (1) reactive state, (2) logic that modifies state, (3) lifecycle hooks for side effects, (4) return refs.
Always return a plain object containing refs. Never return a reactive() object —
it loses reactivity on destructure. If the consumer wants an object, they can wrap:
const mouse = reactive(useMouse()).
Accept refs, getters, and raw values. Use toValue() (with MaybeRefOrGetter<T> type)
to normalize inputs inside watchEffect so reactive sources are tracked.
onUnmounted() — event listeners, timers,
subscriptions.onMounted() / onUnmounted(), not at
top level.Composables can call other composables — build complex logic by composing simple hooks.
<script setup> or setup() function.<script setup> restores the active instance after await, so composables
work after await in <script setup>.onMounted() is acceptable.| Technique | Drawback |
|---|---|
| Mixins | Unclear property sources, namespace collisions, implicit coupling |
| Renderless components | Extra component instance overhead |
| Utility functions | No reactive state or lifecycle hooks |
Composables are explicit, namespaced through destructuring, and integrate with Vue's reactivity and lifecycle.
defineProps<T>() with an interface.const { title, count = 0 } = defineProps<Props>().withDefaults(defineProps<Props>(), { count: 0 }).
Mutable reference defaults (arrays, objects) must use factory functions with
withDefaults.Use named tuple syntax (3.3+): defineEmits<{ change: [id: number] }>().
ref(0) is Ref<number>.ref<string | number>('2024').ref<User | null>(null).ref<ResponseData>() yields Ref<ResponseData | undefined>.Types are inferred. Use explicit generic only when inference falls short:
computed<string>(() => ...).
Annotate with interface, do not use reactive<T>() generic — the returned type handles
ref unwrapping differently from the generic parameter.
useTemplateRef<HTMLInputElement>('input').useTemplateRef<InstanceType<typeof MyComponent>>('comp').ref<HTMLInputElement | null>(null).Use InjectionKey<T> for type-safe keys. String keys require generic annotation:
inject<string>('key').
Use generic attribute on <script setup>:
<script setup lang="ts" generic="T extends string | number">.
Type DOM events explicitly: (event: Event) then cast target:
event.target as HTMLInputElement.
Use Vue's typed helpers: Ref<T>, ComputedRef<T>, MaybeRefOrGetter<T>,
InjectionKey<T>, PropType<T>, ComponentPublicInstance. Full utility types
table in references/typescript.md.
defineAsyncComponent() for component-level splitting.lodash-es over lodash).<script setup> compiles to more minification-friendly code than Options API.active="item.id === activeId") instead
of raw IDs to prevent unnecessary child re-renders.v-once — render once, skip all future updates. For truly static content.v-memo — conditionally skip sub-tree updates. Accepts a dependency array; only
re-renders when a dependency changes. Use on v-for lists where most items don't
change.vue-virtual-scroller, vueuc/VVirtualList).shallowRef() for large immutable datasets — mutations must replace the whole value.{ deep: true } on large objects — watch specific properties instead.useDebounceFn from
VueUse).app.config.performance = true for Vue-specific performance markers.When writing Vue code:
<script setup> unless there is a documented reason not to.When reviewing Vue code:
This skill provides Vue-specific conventions. The coding skill governs workflow; language skills govern JS/TS choices; this skill governs component architecture, reactivity patterns, and framework API usage.
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.