Agent skill

Vue Patterns

by affaan-m in affaan-m/ECC

Vue.js 3 Composition API patterns, component architecture, reactivity best practices, Pinia state management, Vue Router navigation, and Nuxt SSR patterns.

MITAuto-check passedFrontend & Design

Install Vue Patterns

skills CLI
$ npx skills add affaan-m/ECC --skill vue-patterns -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install affaan-m/ECC vue-patterns --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/affaan-m/ECC.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/vue-patterns .claude/skills/vue-patterns && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
vue-patterns
GitHub stars
276k
Used in
1 other repo
Token cost
~3.3k tokens
SKILL.md length
731 words
Files
1
Skills in repo
673
Repo updated
First seen
Licence
MIT

At a glance

Vue.js 3 Composition API patterns, component architecture, reactivity best practices, Pinia state management, Vue Router navigation, and Nuxt SSR patterns.

  • Works in 10 steps: Project Structure → Component Architecture → Composables (Reusable Logic) → …
  • Reviewing Vue 3
  • SKILL.md covers When to Activate, 1. Project Structure, 2. Component Architecture and 3. Composables (Reusable Logic), plus 6 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Vue Patterns is an agent skill from affaan-m/ECC. Vue.js 3 Composition API patterns, component architecture, reactivity best practices, Pinia state management, Vue Router navigation, and Nuxt SSR patterns. Activates for Vue, Nuxt, Vite, or Pinia projects. Use when building or reviewing Vue 3, Nuxt, or Pinia code — Composition API, reactivity, or router navigation.

Its SKILL.md is about 3.3k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Frontend & Design, covering State management. It works with Vue.js, Nuxt and Vite. The repository describes itself as: The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond. The licence is MIT.

When your agent uses it

  • Reviewing Vue 3
  • Pinia code — Composition API
  • Router navigation

Example prompts

  • “/vue-patterns”

Workflow steps

10 steps, taken from the step headings in SKILL.md.

  1. Project Structure
  2. Component Architecture
  3. Composables (Reusable Logic)
  4. State Management
  5. Vue Router
  6. Template Patterns
  7. Performance
  8. Testing
  9. Nuxt-Specific Patterns
  10. Vue 3.5+ New APIs

What it can do on your machine

Read from SKILL.md and the folder at commit ef648e0. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript and vue).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Vue Patterns loads about 3.3k tokens when it runs. Until then it costs about 82 tokens; SKILL.md has 731 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~82
When it runs · the whole SKILL.md, loaded when a task matches
~3.3k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from affaan-m/ECC at commit ef648e0, republished under its MIT licence (© affaan-m). 731 words, ~3,270 tokens.

Download SKILL.mdSave it as .claude/skills/vue-patterns/SKILL.md (or your agent's skills folder).
name
vue-patterns
description
Vue.js 3 Composition API patterns, component architecture, reactivity best practices, Pinia state management, Vue Router navigation, and Nuxt SSR patterns. Activates for Vue, Nuxt, Vite, or Pinia projects. Use when building or reviewing Vue 3, Nuxt, or Pinia code — Composition API, reactivity, or router navigation.
origin
ECC

Vue.js Patterns and Best Practices

Comprehensive guide for Vue.js 3 development using Composition API (<script setup>), covering component design, reactivity, state management, routing, testing, and SSR patterns. Nuxt-specific guidance is included where it differs from vanilla Vue.

When to Activate

Activate this skill when:

  • The project uses Vue.js (any version), Nuxt, Vite + Vue, or Pinia.
  • The user asks about Vue component architecture, composables, reactivity, or state management.
  • Reviewing Vue Single-File Components (.vue files).
  • Setting up Vue Router, Pinia stores, or Vite/Vitest configuration.
  • Discussing Vue-specific performance, security, or SSR patterns.

1. Project Structure

src/
├── api/              # API client and endpoint definitions
├── assets/           # Static assets (images, fonts, icons)
├── components/       # Shared/reusable components
│   ├── base/         # Base UI primitives (Button, Input, Modal)
│   └── features/     # Feature-specific shared components
├── composables/      # Reusable Composition API logic
├── layouts/          # Page layouts (optional)
├── pages/            # Route-level page components
├── router/           # Vue Router configuration
├── stores/           # Pinia stores
├── types/            # TypeScript type definitions
├── utils/            # Pure utility functions
└── App.vue           # Root component
File Naming
ConventionWhen to Use
PascalCase.vueAll components (enforced by vue/multi-word-component-names)
useCamelCase.tsComposables
camelCase.tsUtilities, API clients, types
kebab-case directoriesRoute segments, feature folders

2. Component Architecture

Single-File Component Order
vue
<script setup lang="ts">
// 1. Imports (vue → ecosystem → absolute → relative)
// 2. Props & Emits & Slots
// 3. Composables
// 4. Local state (ref/reactive)
// 5. Computed properties
// 6. Methods
// 7. Watchers
// 8. Lifecycle hooks
</script>

<template>
  <!-- Template content -->
</template>

<style scoped>
  /* Scoped styles */
</style>
Presentational vs Container
  • Container components: Own data fetching, state, and side effects. Render presentational components.
  • Presentational components: Receive props, emit events. No API calls, no store access. Pure rendering.
Props Best Practices
ts
// Type-based props with defaults
interface Props {
  label: string;
  variant?: "primary" | "secondary";
  disabled?: boolean;
  items: Item[];
}

const props = withDefaults(defineProps<Props>(), {
  variant: "primary",
  disabled: false,
});
  • Always provide type, and required/default where appropriate.
  • Boolean props: isXxx, hasXxx, canXxx.
  • Never mutate props — emit events instead.
  • For v-model binding, use defineModel() (Vue 3.4+) or modelValue + update:modelValue.
Events
ts
const emit = defineEmits<{
  submit: [];
  "update:modelValue": [value: string];
  select: [id: string, index: number];
}>();
  • Use kebab-case in templates (@update:model-value).
  • Use camelCase in script (emit("update:modelValue", val)).

3. Composables (Reusable Logic)

Structure
ts
// composables/useDebounce.ts
export function useDebounce<T>(value: MaybeRef<T>, delay: number): Ref<T> {
  const debounced = ref(toValue(value)) as Ref<T>;

  let timer: ReturnType<typeof setTimeout>;
  watch(
    () => toValue(value),
    (newVal) => {
      clearTimeout(timer);
      timer = setTimeout(() => { debounced.value = newVal; }, delay);
    }
  );

  onUnmounted(() => clearTimeout(timer));
  return readonly(debounced);
}
Rules
  • Must start with use prefix.
  • Return reactive values (ref, computed, reactive), never plain primitives.
  • Accept reactive inputs via MaybeRef / toRef() / toValue().
  • Clean up side effects in onUnmounted or watcher onCleanup.
  • No module-scope side effects.
vs Mixins

Composables replace Vue 2 mixins entirely:

  • Mixins: Opaque data flow, source-of-truth collisions, name conflicts.
  • Composables: Explicit imports, clear return values, composable and tree-shakable.

4. State Management

When to Use What
PatternUse Case
ref() / reactive()Local component state
Props + EmitsParent-child communication
Provide / InjectTheme, config, plugin API
Pinia storeGlobal, shared, complex state
Server state composableAPI data with caching (wrap fetch/TanStack Query)
Pinia Setup Store (Preferred)
ts
// stores/useCartStore.ts
export const useCartStore = defineStore("cart", () => {
  const items = ref<CartItem[]>([]);
  const isLoading = ref(false);

  const totalPrice = computed(() =>
    items.value.reduce((sum, i) => sum + i.price * i.quantity, 0)
  );
  const itemCount = computed(() =>
    items.value.reduce((sum, i) => sum + i.quantity, 0)
  );

  async function addItem(productId: string) {
    isLoading.value = true;
    try {
      const item = await fetchProduct(productId);
      const existing = items.value.find(i => i.id === item.id);
      if (existing) existing.quantity++;
      else items.value.push({ ...item, quantity: 1 });
    } finally {
      isLoading.value = false;
    }
  }

  return { items, isLoading, totalPrice, itemCount, addItem };
});
  • Use Setup Store syntax (not Options Store).
  • Prefer actions for business-level mutations and $patch() for grouped updates.
  • Every async action: handle loading + success + error.

5. Vue Router

Route Definitions
ts
const routes = [
  {
    path: "/users/:id",
    name: "user-detail",
    component: () => import("@/pages/UserDetail.vue"), // lazy
    props: true, // pass params as props
    meta: { requiresAuth: true },
  },
];
Navigation Guards
ts
router.beforeEach((to, from) => {
  const { isLoggedIn } = useAuthStore();
  if (to.meta.requiresAuth && !isLoggedIn) {
    return { name: "login", query: { redirect: to.fullPath } };
  }
});
Reactive Route Params

When a component stays mounted but route params change:

ts
const route = useRoute();
const id = computed(() => route.params.id as string);
watch(id, (newId) => fetchItem(newId));

6. Template Patterns

Template Syntax
vue
<!-- v-if/v-else-if/v-else -->
<div v-if="isLoading">Loading...</div>
<div v-else-if="error">Error: {{ error }}</div>
<div v-else>{{ content }}</div>

<!-- v-show for frequent toggles -->
<div v-show="isOpen">Toggled content</div>

<!-- v-for with stable keys -->
<div v-for="item in items" :key="item.id">{{ item.name }}</div>

<!-- Computed filtered list (not v-if + v-for on same element) -->
<div v-for="item in activeItems" :key="item.id">{{ item.name }}</div>

<!-- Event handling -->
<form @submit.prevent="handleSubmit">
  <button type="submit">Save</button>
</form>

<!-- v-model -->
<input v-model="name" />
<CustomInput v-model="value" v-model:title="title" />

7. Performance

TechniqueWhen to Use
v-memoList items that rarely change
v-onceContent rendered once and static forever
shallowRef()Large data structures replaced wholesale
shallowReactive()Only top-level properties are reactive
v-show over v-ifFrequent visibility toggles
<KeepAlive :max="10">Cache toggled views
Lazy routes() => import(...) for non-critical routes
SuspenseAsync component loading with fallback

8. Testing

Stack
  • Vitest for unit and component tests
  • Vue Test Utils for mounting and interaction
  • @pinia/testing for store mocking
  • Playwright for E2E
Component Test Pattern
ts
import { mount } from "@vue/test-utils";
import { createPinia, setActivePinia } from "pinia";
import UserCard from "./UserCard.vue";

beforeEach(() => { setActivePinia(createPinia()); });

it("renders and emits", async () => {
  const wrapper = mount(UserCard, {
    props: { user: { id: "1", name: "Alice" } },
  });
  expect(wrapper.text()).toContain("Alice");
  await wrapper.find("button").trigger("click");
  expect(wrapper.emitted("select")![0]).toEqual(["1"]);
});

9. Nuxt-Specific Patterns

Show full SKILL.md (292 more words)Show less
Auto-Imports

Nuxt auto-imports ref, computed, watch, useFetch, useAsyncData, etc. Use them directly without importing. For non-Nuxt projects, always import explicitly.

useAsyncData / useFetch
ts
const { data: user, pending, error, refresh } = await useAsyncData(
  "user", // unique key for caching
  () => $fetch(`/api/users/${id}`),
);

const { data: posts } = await useFetch("/api/posts", {
  query: { page: 1 },
  key: "posts-page-1", // dedupes requests
});
Server Routes
ts
// server/api/users/[id].ts
export default defineEventHandler(async (event) => {
  const { id } = await getValidatedRouterParams(event, z.object({
    id: z.string().uuid(),
  }).parse);
  // ... fetch and return
});
Runtime Config
ts
// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    // server-only
    apiSecret: "",
    // public (exposed to client)
    public: {
      apiBase: "https://api.example.com",
    },
  },
});

10. Vue 3.5+ New APIs

Reactive Props Destructure

Vue 3.5 stabilized reactive props destructure — destructured variables from defineProps() are automatically reactive:

ts
// Vue 3.5+: destructured props are reactive (no need for toRefs)
const { count = 0, msg = "hello" } = defineProps<{
  count?: number;
  msg?: string;
}>();

// Limitation: cannot watch destructured prop directly
watch(() => count, (newVal) => { ... }); // PASS getter required
useTemplateRef()

Replace name-matched plain refs with useTemplateRef() for template references:

ts
import { useTemplateRef } from "vue";
const inputEl = useTemplateRef<HTMLInputElement>("input");
// "input" matches the ref="input" attribute in template, not the variable name

Supports dynamic ref IDs: useTemplateRef(dynamicRefId).

onWatcherCleanup()

Globally importable watcher cleanup API (Vue 3.5+). It must be called synchronously inside the watcher callback:

ts
import { watch, onWatcherCleanup } from "vue";

watch(userId, async (newId) => {
  const controller = new AbortController();
  onWatcherCleanup(() => controller.abort());
  // ... fetch with signal
});
useId()

SSR-stable unique ID generation for form elements and accessibility:

ts
import { useId } from "vue";
const id = useId();
defer Teleport

<Teleport defer> allows teleporting to targets rendered in the same cycle:

vue
<Teleport defer to="#container">Content</Teleport>
<div id="container"></div>
Lazy Hydration (SSR)

defineAsyncComponent() now supports hydrate strategy:

ts
import { defineAsyncComponent, hydrateOnVisible } from "vue";
const AsyncComp = defineAsyncComponent({
  loader: () => import("./Comp.vue"),
  hydrate: hydrateOnVisible(),
});

Anti-Patterns

Anti-PatternWhy It's WrongThe Fix
Destructuring defineProps() (Vue < 3.5)Captures snapshot, loses reactivityAccess via props.xxx or use toRefs()
watch() on destructured prop (Vue 3.5+)Compile-time error — destructured props can't be watched directlyUse getter wrapper: watch(() => count, ...)
v-if + v-for on same elementAmbiguous execution orderUse computed filtered array
v-for key = indexBroken state on reorderUse stable database IDs
Mutating propsViolates one-way data flowEmit events or use v-model
v-html with user contentXSS vulnerabilitySanitize with DOMPurify
Mixins in Vue 3Opaque, collision-proneReplace with composables
Module-scope side effects in composableShared across instancesScope in onMounted + onUnmounted
reactive() for replaceable stateReplacement breaks reactivityUse ref() instead
Watcher without cleanupMemory leaks, race conditionsUse onCleanup or onWatcherCleanup() (Vue 3.5+)
Options API in new Vue 3 codeEcosystem move to Composition APIUse <script setup>
Plain ref for template referencesNo dynamic ref support, name-matching fragileUse useTemplateRef() (Vue 3.5+)
  • accessibility — ARIA, semantic HTML, focus management
  • frontend-patterns — Cross-framework frontend architecture
  • typescript — TypeScript best practices applied to Vue projects
  • coding-standards — General code quality standards

© affaan-m, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/vue-patterns of affaan-m/ECC.

Open the folder on GitHubat commit ef648e0

Used in 1 other repository

We found 2 copies of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in affaan-m/ECC, which our catalogue first saw on October 7, 2026.

Compare with similar skills

Vue Patterns next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Vue Patterns compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Vue Patterns this skillaffaan-m/ECC276k1 repos~3.3kAutomated safety check: PassMIT
Vue ExpertJeffallan/claude-skills12k—~1.1kAutomated safety check: PassMIT
Nuxt UImegaarmos/vue-spring-bottom-sheet1411 repos~2.5kAutomated safety check: PassMIT
Feature Sliced Designfeature-sliced/skills109—~5.5kAutomated safety check: PassNone
Vue Expert (JavaScript)Jeffallan/claude-skills12k—~1.6kAutomated safety check: PassMIT
PiniaJetBrains/skills3669 repos~682Automated safety check: PassNone

Similar skills

  • Vue Expert

    Jeffallan/claude-skills

    Builds Vue 3 apps with the Composition API and script setup, Pinia state, Nuxt 3, Vite tuning and Quasar or Capacitor mobile builds, checked with vue-tsc and Vitest.

    12k GitHub stars~1.1k tokensUpdated 6 days ago
    Frontend & DesignAuto-check passed
  • Nuxt UI

    megaarmos/vue-spring-bottom-sheet

    Build UIs with @nuxt/ui v4 — 125+ accessible Vue components with Tailwind CSS theming.

    141 GitHub starsUsed in 1 repo~2.5k tokens
    Frontend & DesignAuto-check passed
  • Feature Sliced Design

    feature-sliced/skills

    Official Feature-Sliced Design (FSD) v2.1 skill for applying the methodology to frontend projects.

    109 GitHub stars~5.5k tokensUpdated 2 days ago
    Frontend & DesignAuto-check passed
  • Vue Expert (JavaScript)

    Jeffallan/claude-skills

    Builds Vue 3 apps in plain JavaScript with JSDoc typing instead of TypeScript: script setup components, composables, Pinia and Vitest, with ESLint JSDoc coverage checks.

    12k GitHub stars~1.6k tokensUpdated 6 days ago
    Frontend & DesignAuto-check passed
  • Pinia

    JetBrains/skills

    Official

    Pinia official Vue state management library, type-safe and extensible.

    366 GitHub starsUsed in 9 repos~682 tokens
    Frontend & DesignAuto-check passed
  • Pinia V3

    secondsky/claude-skills

    Pinia v3 Vue state management with defineStore, getters, actions.

    227 GitHub stars~4.5k tokensUpdated 11 days ago
    Frontend & DesignAuto-check passed

More from affaan-m/ECC

All 673 skills in this repo
  • Skill Stocktake

    affaan-m/ECC

    Audits your installed Claude skills and commands for quality, with a quick mode for recently changed skills and a full mode that evaluates all of them through subagents.

    276k GitHub starsUsed in 5 repos~1.9k tokens
    Auto-check passed
  • Ingests, indexes, searches, edits and monitors video, audio and live streams through the VideoDB Python SDK, returning stream links, clips and timestamps.

    276k GitHub starsUsed in 3 repos~3.5k tokens
    Auto-check: notes
  • Rules Distillation

    affaan-m/ECC

    Scans installed skills for principles that recur across them and proposes rule-file changes: append, revise, add a section, create a file or leave as covered.

    276k GitHub starsUsed in 2 repos~2.3k tokens
    Auto-check passed
  • Builds DRAFT counterparty agreements from one markdown template and a small JSON spec per party, with clauses picked by the party's role.

    276k GitHub stars~2.9k tokensUpdated 4 days ago
    Auto-check passed
  • Measures whether agents actually follow a skill, rule or agent definition by generating scenarios at three strictness levels and scoring tool-call traces.

    276k GitHub starsUsed in 1 repo~623 tokens
    Auto-check passed
  • Instinct-based learning system that observes sessions via hooks, creates atomic instincts with confidence scoring, and evolves them into skills/commands/agents.

    276k GitHub stars~3.5k tokensUpdated 4 days ago
    Auto-check passed

Works with

Questions about Vue Patterns

What does Vue Patterns do?

Vue.js 3 Composition API patterns, component architecture, reactivity best practices, Pinia state management, Vue Router navigation, and Nuxt SSR patterns. Vue Patterns is an agent skill from affaan-m/ECC.js 3 Composition API patterns, component architecture, reactivity best practices, Pinia state management, Vue Router navigation, and Nuxt SSR patterns.

When should I use Vue Patterns?

Vue Patterns fits situations like: reviewing Vue 3; pinia code — Composition API; router navigation.

How do I install Vue Patterns in Claude Code?

Run `npx skills add affaan-m/ECC --skill vue-patterns -a claude-code`. Or copy the skill folder (skills/vue-patterns in affaan-m/ECC) into .claude/skills/vue-patterns in your project. Claude Code loads it when a task matches its description.

How do I install Vue Patterns in Codex?

Run `npx skills add affaan-m/ECC --skill vue-patterns -a codex`. Or copy the skill folder (skills/vue-patterns in affaan-m/ECC) into .agents/skills/vue-patterns in your project. Codex loads it when a task matches its description.

Can I use Vue Patterns in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add affaan-m/ECC --skill vue-patterns -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/vue-patterns, .gemini/skills/vue-patterns, .github/skills/vue-patterns and .opencode/skills/vue-patterns in your project.

What does Vue Patterns need to run?

SKILL.md names no scripts, command-line tools or credentials: Vue Patterns is instructions for the agent only.

Does Vue Patterns access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Vue Patterns safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Vue Patterns use?

Vue Patterns is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Vue Patterns use?

About 3.3k tokens (SKILL.md is roughly 13k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Vue Patterns?

Skills that share tags, products or a category with Vue Patterns: Vue Expert (Jeffallan/claude-skills, 12k stars), Nuxt UI (megaarmos/vue-spring-bottom-sheet, 141 stars), Feature Sliced Design (feature-sliced/skills, 109 stars) and Vue Expert (JavaScript) (Jeffallan/claude-skills, 12k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Vue Patterns?

affaan-m (a GitHub user) maintains it in affaan-m/ECC, which has 275,546 GitHub stars. The repository holds 673 skills in this directory. The repository was last updated on October 5, 2026.

Source: affaan-m/ECC on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.