Skip to content

// Build Vue 3 apps with Composition API, Pinia, Vue Router 4, and Vite.

Vue 3 Composition API

skill --stat
  • last update

    Apr 28, 2026

  • license

    MITv1.0.0

  • format

    SKILL.md

quickstart.sh
3 steps
  1. Install

    // Downloads SKILL.md into ~/.claude/skills/vuejs-3-composition/

    $ curl -fsSL --create-dirs -o ~/.claude/skills/vuejs-3-composition/SKILL.md https://claudeskil.com/skills/vuejs-3-composition/SKILL.md
  2. Invoke

    // Inside Claude Code, type the skill name as a slash command

    > /vuejs-3-composition give my landing page a hero treatment
  3. Or copy this from the README

    // extracted vue block

    $ <script setup lang="ts">
    import { storeToRefs } from 'pinia'
    import { useCounterStore } from '@/stores/counter'
    
    const store = useCounterStore()
    const { count, double } = storeToRefs(store) // keeps reactivity
vuejs-3-composition/
references
SKILL.md
readonly
name:
Vue 3 Composition API
slug:
vuejs-3-composition
version:
v1.0.0
license:
MIT
author:
@chiragthummar16
categories:
tags:
#vuejs#composition-api#pinia#vite#typescript#nuxt
description:

Build Vue 3 apps with Composition API, Pinia, Vue Router 4, and Vite.

README.md

vuejs-3-composition/README.md
6 sections

Vue 3 Composition API

A focused assistant for building Vue 3 applications the modern way: <script setup> single-file components, Pinia for state, Vue Router 4 for navigation, and Vite as the dev server and bundler. It writes TypeScript-first code with correctly typed props, emits, and store state, and it understands the Nuxt 3 conventions if your project lives there instead. This is for developers who have left the Options API behind and want idiomatic, reactive code without re-litigating ref vs reactive every time.

When to use it

  • Scaffolding a new component and you want defineProps<T>() / defineEmits<T>() with proper generic typing rather than runtime declarations.
  • Standing up a Pinia store and wiring it into components without losing reactivity through destructuring.
  • Configuring Vue Router 4 — nested routes, route guards, lazy-loaded views, typed useRoute/useRouter.
  • Migrating an Options API component to <script setup>.
  • Setting up or debugging a Vite + Vue project, including path aliases and the @vitejs/plugin-vue config.

How it works

It generates <script setup lang="ts"> SFCs using the core reactivity primitives — ref, reactive, computed, watch, watchEffect — and lifecycle hooks like onMounted and onUnmounted. Stores are written with Pinia's defineStore (setup-style, returning refs and functions), and consumed via storeToRefs() so reactivity survives destructuring. Router setup uses createRouter with createWebHistory, and it knows defineAsyncComponent and dynamic import() for code-splitting routes. For Nuxt 3 it follows file-based routing, auto-imports, and useFetch/useAsyncData.

Example

bash
curl -fsSL --create-dirs -o ~/.claude/skills/vuejs-3-composition/SKILL.md https://claudeskil.com/skills/vuejs-3-composition/SKILL.md
vue
<script setup lang="ts">
import { storeToRefs } from 'pinia'
import { useCounterStore } from '@/stores/counter'

const store = useCounterStore()
const { count, double } = storeToRefs(store) // keeps reactivity
</script>

<template>
  <button @click="store.increment">{{ count }} / {{ double }}</button>
</template>
ts
// stores/counter.ts
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const double = computed(() => count.value * 2)
  function increment() { count.value++ }
  return { count, double, increment }
})

Tips & gotchas

  • Destructuring a store directly drops reactivity — always wrap state/getters in storeToRefs(), but keep actions off it (call them on the store object).
  • defineProps/defineEmits are compiler macros: don't import them, and don't reference outer-scope variables in their type arguments.
  • Props are reactive only if you don't destructure them (pre-3.5) — use toRefs(props) or access props.x directly.
  • In Nuxt, useFetch dedupes by key; pass an explicit key when calling it twice with the same URL.

FAQ

ref or reactive? Default to ref for everything — it's consistent, works for primitives, and survives reassignment. Reserve reactive for tightly grouped object state you'll never replace wholesale.

Does it support the Options API? It can read and migrate Options API code, but it generates Composition API / <script setup> by default.

Pinia or Vuex? Pinia. It's the official recommendation for Vue 3 and the skill targets its setup-store syntax.

$ cat reviews/

Reviews

// No reviews yet. Be the first.
Loading review form…

$ ls related/

explore all →