Agent skill

Vue Idioms

by irahardianto in irahardianto/awesome-agv

Vue 3 Composition API patterns: <script setup syntax, reactive state with Pinia stores, reusable composables, and Vitest component testing.

MITAuto-check passedTesting & QA

Install Vue Idioms

skills CLI
$ npx skills add irahardianto/awesome-agv --skill vue-idioms -a claude-code

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

GitHub CLI
$ gh skill install irahardianto/awesome-agv vue-idioms --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/irahardianto/awesome-agv.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/vue-idioms .claude/skills/vue-idioms && 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-idioms
GitHub stars
156
Token cost
~6k tokens
SKILL.md length
1,272 words
Files
3 (incl. references)
Skills in repo
34
Repo updated
First seen
Licence
MIT

At a glance

Vue 3 Composition API patterns: <script setup syntax, reactive state with Pinia stores, reusable composables, and Vitest component testing.

  • Works in 3 steps: Use computed for all derived state —… → Never cause side effects inside computed… → Use writable computed for two-way bindings
  • Refactoring Vue 3 frontend applications
  • SKILL.md covers Vue Idioms and Patterns and When to Load References
  • Calls tsc, vitest and eslint; needs TASK_API_KEY

What it does

Vue Idioms is an agent skill from irahardianto/awesome-agv. Vue 3 Composition API patterns: <script setup syntax, reactive state with Pinia stores, reusable composables, and Vitest component testing. Use when developing or refactoring Vue 3 frontend applications.

Its SKILL.md is about 6k tokens, which your agent loads only when the skill is triggered. The skill folder holds 3 other files, including reference files (for example `references/project-structure.md` and `references/recommended-dependencies.md`).

It sits in Testing & QA, covering Unit testing and Refactoring. It works with Vue.js, Vitest, TypeScript and Zod. The repository describes itself as: Comprehensive sets of standards and practices designed to elevate the capabilities of AI coding agents. The licence is MIT.

When your agent uses it

  • Refactoring Vue 3 frontend applications
  • Tasks that involve Unit testing
  • Tasks that involve Refactoring

Example prompts

  • “/vue-idioms”

Requirements

  • A credential in TASK_API_KEY

Workflow steps

3 steps, taken from the first numbered list in SKILL.md.

  1. Use computed for all derived state — never recompute in the template
  2. Never cause side effects inside computed — computed must be pure
  3. Use writable computed for two-way bindings

What it can do on your machine

Read from SKILL.md and the folder at commit 9e997ba. 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

    Shell commands in SKILL.md call:

    • tsc
    • vitest
    • eslint
    • prettier

    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 these keys or tokens, usually read from environment variables:

    • TASK_API_KEY

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

Context cost

Vue Idioms loads about 6k tokens when it runs, and up to ~8k if it reads all its reference files. Until then it costs about 54 tokens; SKILL.md has 1,272 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~54
When it runs · the whole SKILL.md, loaded when a task matches
~6k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~8k

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 irahardianto/awesome-agv at commit 9e997ba, republished under its MIT licence (© irahardianto). 1,272 words, ~5,986 tokens.

Download SKILL.mdSave it as .claude/skills/vue-idioms/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.
name
vue-idioms
description
Vue 3 Composition API patterns: `<script setup>` syntax, reactive state with Pinia stores, reusable composables, and Vitest component testing. Use when developing or refactoring Vue 3 frontend applications.

Vue Idioms and Patterns

Core Philosophy

Vue 3 Composition API is the default for all new code. <script setup> is the canonical syntax. Think in terms of reactive data flows, not component lifecycle hooks. Composables (use* functions) are the primary unit of logic reuse.

Scope: This file covers Vue 3 coding idioms for components, stores, and composables. For TypeScript type system patterns, see @.agents/skills/typescript-idioms/SKILL.md. For file and folder layout, see references/project-structure.md (and the shared @.agents/skills/frontend-design/references/frontend-layout.md). For test naming, see @.agents/rules/testing-strategy.md. For logging, see @.agents/skills/logging-implementation/SKILL.md.

Loading guard: Do NOT load this skill for non-Vue projects. React → react-idioms; Angular → angular-idioms; Next.js → nextjs-idioms. This skill co-loads with typescript-idioms (required for any Vue work).

When to Load References

Always load typescript-idioms first — it is required alongside this skill for any Vue work. Load these before writing code in the matching context — not after.

SituationReference to Load
TypeScript type system, async, Zod, error types@.agents/skills/typescript-idioms/SKILL.md (always co-load)
Starting a new Vue project or reviewing file layoutreferences/project-structure.md
Choosing Vue ecosystem package versions, Vite/Vitest configreferences/recommended-dependencies.md
Defining Zod schemas or validating boundaries@.agents/skills/typescript-idioms/references/zod-patterns.md
Writing code that handles user input, async, or I/O@.agents/skills/typescript-idioms/references/ts-patterns-and-anti-patterns.md
Toolchain and Version Milestones

Default to the latest Vue 3 stable. As of July 2026, Vue 3.5+ with Vite 6+.

Key version milestones that affect this skill:

  • 3.5+ — useTemplateRef (type-safe template refs), improved useId, Suspense stable
  • 3.4+ — defineModel (replaces verbose v-model boilerplate), improved watch generics
  • 3.3+ — defineOptions, defineSlots, generic components with <script setup>
  • 3.2+ — <script setup> syntax finalized

For recommended package versions and starter configs, see references/recommended-dependencies.md.


<script setup> — The Only Style

Always use <script setup lang="ts">. Never use the Options API or the class-style component pattern for new code.

vue
<!-- ✅ Canonical style -->
<script setup lang="ts">
import { ref, computed } from 'vue';

const props = defineProps<{ title: string; count?: number }>();
const emit = defineEmits<{ 'update:count': [value: number] }>();

const doubled = computed(() => (props.count ?? 0) * 2);
</script>

<!-- ❌ Options API — do not use for new components -->
<script lang="ts">
export default { props: { title: String }, ... }
</script>

Reactivity: ref vs reactive
UseWhen
ref<T>()Primitives, single values, values that may be reassigned
reactive()Plain objects where you always access properties (never reassign the whole object)
readonly()Expose state that must not be mutated outside its owner
typescript
// ✅ ref for primitives and replaceable objects
const count = ref(0);
const user = ref<User | null>(null);
user.value = fetchedUser; // reassignment is fine

// ✅ reactive for objects where you destructure properties
const form = reactive({ title: '', priority: 'medium' });

// ❌ Never destructure a reactive object — reactivity is lost
const { title } = form; // title is now a plain string, NOT reactive
// ✅ Use toRefs if you must destructure
const { title } = toRefs(form);

Computed Properties
  1. Use computed for all derived state — never recompute in the template

    typescript
    // ✅ Cached, reactive
    const filteredTasks = computed(() =>
        tasks.value.filter(t => t.status === activeFilter.value)
    );
    
    // ❌ Recomputes on every render
    // <template>{{ tasks.filter(t => t.status === filter) }}</template>
  2. Never cause side effects inside computed — computed must be pure

    typescript
    // ❌ Side effect in computed
    const count = computed(() => {
        taskStore.logAccess(); // NO — this is a side effect
        return tasks.value.length;
    });
  3. Use writable computed for two-way bindings

    typescript
    const modelValue = computed({
        get: () => props.modelValue,
        set: (val) => emit('update:modelValue', val),
    });

Watch Strategy

Use the most precise watcher for the situation — over-watching is a performance and correctness problem.

WatcherUse When
watchEffectSide effect that should re-run whenever any of its reactive dependencies change; auto-tracks dependencies
watchYou need the old value, lazy execution, or want to watch a specific source explicitly
computedYou need a synchronous derived value (prefer this over watch for transformation)
typescript
// ✅ watchEffect — auto-tracks dependencies
watchEffect(() => {
    document.title = `Tasks (${count.value})`;
});

// ✅ watch — explicit source, has old value
watch(userId, async (newId, oldId) => {
    if (newId !== oldId) await loadUser(newId);
}, { immediate: true });

// ❌ Avoid using watch just for computed values
watch(tasks, () => { filteredCount.value = tasks.value.filter(...).length; });
// ✅ Use computed instead
const filteredCount = computed(() => tasks.value.filter(...).length);

Pinia Stores

The store directory structure is defined in references/project-structure.md. This section covers Pinia coding idioms.

  1. Use the Setup Store API (not Options API) for new stores

    typescript
    // task/store/task.store.ts
    export const useTaskStore = defineStore('task', () => {
        // State
        const tasks = ref<Task[]>([]);
        const isLoading = ref(false);
    
        // Getters (computed)
        const completedTasks = computed(() =>
            tasks.value.filter(t => t.status === 'done')
        );
    
        // Actions
        async function loadTasks() {
            isLoading.value = true;
            try {
                tasks.value = await taskAPI.getTasks();
            } finally {
                isLoading.value = false;
            }
        }
    
        return { tasks, isLoading, completedTasks, loadTasks };
    });
  2. Never mutate store state from outside the store

    typescript
    // ❌ Direct mutation from a component
    const store = useTaskStore();
    store.tasks.push(newTask); // NO
    
    // ✅ Call an action
    await store.addTask(newTask);
  3. Inject the API dependency — never import it directly inside the store

    typescript
    // ✅ Receives the API interface — testable with createTestingPinia + mock API
    export const useTaskStore = defineStore('task', () => {
        const api = inject<TaskAPI>(TASK_API_KEY);
        if (!api) throw new Error('[TaskStore] TASK_API_KEY not provided — ensure app.provide() is called before store access');
        // ...
    });
  4. Use storeToRefs when destructuring a store in components

    typescript
    // ✅ Preserves reactivity
    const { tasks, isLoading } = storeToRefs(useTaskStore());
    const { loadTasks } = useTaskStore(); // actions don't need storeToRefs

Composables (use* Functions)

Composables are the Vue equivalent of custom hooks — self-contained, reusable units of reactive logic.

  1. Naming: always prefix with use

    • useTaskFilters, useAuth, usePagination
  2. Return reactive refs, not raw values

    typescript
    // ✅ Caller can use returned values reactively
    function useCounter(initial = 0) {
        const count = ref(initial);
        const increment = () => count.value++;
        return { count, increment };
    }
    
    // ❌ count is a plain number — not reactive
    function useCounter() {
        let count = 0;
        return { count };
    }
  3. Always clean up side effects in onUnmounted

    typescript
    function useWindowResize() {
        const width = ref(window.innerWidth);
        const handler = () => (width.value = window.innerWidth);
    
        onMounted(() => window.addEventListener('resize', handler));
        onUnmounted(() => window.removeEventListener('resize', handler)); // ✅ cleanup
        return { width };
    }
  4. Template refs with useTemplateRef (Vue 3.5+) — type-safe, IDE-friendly replacement for ref(null)

    typescript
    // ✅ Vue 3.5+ — useTemplateRef provides fully typed access
    const inputEl = useTemplateRef<HTMLInputElement>('myInput');
    // <input ref="myInput" />
    
    // ❌ Old pattern (before 3.5) — less type-safe
    const inputEl = ref<HTMLInputElement | null>(null);
  5. Feature-specific composables live inside the feature directory — global composables go in src/composables/. See references/project-structure.md.


Component Design
  1. defineProps with TypeScript generics — no runtime validators for typed props

    typescript
    const props = defineProps<{
        taskId: string;
        variant?: 'compact' | 'full';
    }>();
    
    // Defaults via withDefaults
    const props = withDefaults(defineProps<{ variant?: 'compact' | 'full' }>(), {
        variant: 'full',
    });
  2. defineEmits with typed event signatures

    typescript
    const emit = defineEmits<{
        'update:modelValue': [value: string];
        'submit': [task: CreateTaskRequest];
    }>();
  3. defineModel (Vue 3.4+) — preferred v-model pattern

    vue
    <script setup lang="ts">
    // ✅ Vue 3.4+ — one line replaces modelValue prop + emit boilerplate
    const modelValue = defineModel<string>({ required: true });
    
    // Named models for multi-v-model components
    const title = defineModel<string>('title');
    const priority = defineModel<'low' | 'medium' | 'high'>('priority', { default: 'medium' });
    </script>
    
    <!-- Usage by parent: <TaskForm v-model="name" v-model:priority="prio" /> -->

    Pre-3.4 fallback (when defineModel is unavailable):

    typescript
    // ❌ Verbose — use defineModel instead on Vue 3.4+
    const props = defineProps<{ modelValue: string }>();
    const emit = defineEmits<{ 'update:modelValue': [value: string] }>();
  4. defineExpose to selectively expose methods to parent refs

    typescript
    // Everything in <script setup> is private by default.
    // Use defineExpose only for intentional parent access (e.g., form.reset()).
    defineExpose({ reset, focus });
    // ❌ Without defineExpose: parent ref.value.reset() will be undefined
  5. v-bind="$attrs" and inheritAttrs: false for forwarding attributes

    typescript
    // Avoid prop drilling for HTML attributes — forward them to the root element
    defineOptions({ inheritAttrs: false });
    // In template: <input v-bind="$attrs" />
  6. One concern per component — if the template exceeds 100 lines (excluding boilerplate), extract a sub-component

  7. Never put business logic in the template — computed and composables belong in <script setup>


Template Patterns
  1. Always bind :key with stable, unique IDs in v-for — never use index as key when list order can change

    html
    <!-- ✅ Stable key -->
    <TaskCard v-for="task in tasks" :key="task.id" :task="task" />
    
    <!-- ❌ Index key — causes rerender bugs when list reordered -->
    <TaskCard v-for="(task, i) in tasks" :key="i" :task="task" />
  2. Never combine v-if and v-for on the same element — wrap with <template>

    html
    <!-- ✅ -->
    <template v-for="task in tasks" :key="task.id">
        <TaskCard v-if="task.visible" :task="task" />
    </template>

Route Transitions

When using <Transition> or <RouterView> with transition effects, CSS frameworks that use @layer (Tailwind v4, Open Props, UnoCSS) can silently break SPA navigation by overriding transition properties in the cascade. This causes transitionend to never fire, permanently blocking the entering component.

  1. Avoid mode="out-in" when using @layer-based CSS frameworks — the leaving component's transitionend event may never fire, blocking the entering component indefinitely. Use simultaneous transitions instead:

    html
    <!-- ❌ Dangerous with @layer CSS frameworks -->
    <Transition name="fade" mode="out-in">
      <component :is="Component" />
    </Transition>
    
    <!-- ✅ Safe: simultaneous leave/enter, always mounts new component -->
    <Transition name="fade">
      <component :is="Component" :key="$route.path" />
    </Transition>
  2. Always bind :key="$route.path" on dynamic <component> inside <Transition> — forces Vue to treat each route as a distinct component instance, ensuring proper enter/leave lifecycle

  3. Use !important on route transition CSS classes — guarantees transition properties win the @layer cascade:

    css
    .fade-enter-active {
      transition: opacity 0.15s ease-in !important;
    }
    .fade-leave-active {
      transition: opacity 0.15s ease-out !important;
      position: absolute !important;
      width: 100% !important;
      top: 0 !important;
      left: 0 !important;
    }
    .fade-enter-from,
    .fade-leave-to {
      opacity: 0 !important;
    }
  4. Give the transition parent position: relative — contains the absolutely-positioned leaving element during the simultaneous transition overlap

For full diagnosis steps when a transition-stuck blank screen occurs, see the Debugging Protocol's Frontend module: @.agents/skills/debugging-protocol/languages/frontend.md § CSS × Animation.


Show full SKILL.md (822 more words)Show less
Error Handling

For error type hierarchies, custom error classes, and Result<T, E>, see @.agents/skills/typescript-idioms/SKILL.md §Error Handling. This section covers Vue-specific error handling only.

  1. Global error handler — register at app startup:

    typescript
    // main.ts — catches all unhandled errors in any component
    app.config.errorHandler = (err, instance, info) => {
      logger.error('Unhandled Vue error', {
        error: err instanceof Error ? err.message : String(err),
        componentInfo: info,
        stack: err instanceof Error ? err.stack : undefined,
      });
    };
  2. Component-level error capture with onErrorCaptured:

    typescript
    // ✅ Catches errors from child component tree — use for error boundary components
    const error = ref<Error | null>(null);
    onErrorCaptured((err) => {
      error.value = err instanceof Error ? err : new Error(String(err));
      return false; // stop propagation to parent
    });
  3. Async errors in lifecycle hooks — always handle:

    typescript
    // ❌ Floating promise — error silently lost
    onMounted(() => { loadTasks(); });
    
    // ✅ Catch and surface to reactive error state
    onMounted(async () => {
      try {
        await loadTasks();
      } catch (err) {
        error.value = err instanceof Error ? err : new Error(String(err));
      }
    });

Form Handling

For Zod schema patterns, see @.agents/skills/typescript-idioms/references/zod-patterns.md. This section covers Vue-specific form binding only.

  1. defineModel for simple forms (Vue 3.4+) — see Component Design §3 above.

  2. VeeValidate + Zod for validated forms:

    vue
    <script setup lang="ts">
    import { useForm, useField } from 'vee-validate';
    import { toTypedSchema } from '@vee-validate/zod';
    import { z } from 'zod';
    
    const schema = toTypedSchema(z.object({
      title: z.string().min(1, 'Title is required').max(200),
      priority: z.enum(['low', 'medium', 'high']),
    }));
    
    const { handleSubmit, errors } = useForm({ validationSchema: schema });
    const { value: title } = useField<string>('title');
    const { value: priority } = useField<string>('priority');
    
    const onSubmit = handleSubmit(async (values) => {
      await taskStore.createTask(values);
    });
    </script>
    
    <template>
      <form @submit="onSubmit">
        <input v-model="title" />
        <span v-if="errors.title">{{ errors.title }}</span>
        <select v-model="priority">
          <option value="low">Low</option>
          <option value="medium">Medium</option>
          <option value="high">High</option>
        </select>
        <button type="submit">Create</button>
      </form>
    </template>
  3. Client-side validation is UX, not security — always validate at the API boundary too. See @.agents/rules/security-principles.md.


Performance

Profile before optimizing — see @.agents/skills/perf-optimization/SKILL.md for methodology. This section covers Vue-specific patterns only.

  1. defineAsyncComponent for lazy loading heavy components:

    typescript
    import { defineAsyncComponent } from 'vue';
    const HeavyChart = defineAsyncComponent(() => import('./HeavyChart.vue'));
  2. Lazy route loading with Vue Router:

    typescript
    const routes = [
      { path: '/tasks', component: () => import('../views/TaskView.vue') },
      { path: '/settings', component: () => import('../views/SettingsView.vue') },
    ];
  3. <KeepAlive> for caching expensive component state:

    html
    <!-- Caches up to 10 component instances — avoids teardown/remount cost -->
    <KeepAlive :max="10">
      <component :is="currentTab" />
    </KeepAlive>
  4. v-memo for expensive list rendering (Vue 3.2+):

    html
    <!-- Re-renders item only when its id or selected state changes -->
    <div v-for="item in list" :key="item.id" v-memo="[item.id, item === selected]">
      <ExpensiveComponent :item="item" />
    </div>
  5. v-once for static content that never changes:

    html
    <footer v-once>© 2026 Acme Corp</footer>

Testing

For test naming, pyramid ratios, and the AAA pattern, see @.agents/rules/testing-strategy.md. This section covers Vue-specific tooling only.

  1. Mount wrapper with @vue/test-utils + createTestingPinia:

    typescript
    import { mount } from '@vue/test-utils';
    import { createTestingPinia } from '@pinia/testing';
    import { vi } from 'vitest';
    
    function mountComponent(overrides: Record<string, unknown> = {}) {
      return mount(TaskView, {
        global: {
          plugins: [createTestingPinia({ createSpy: vi.fn })],
          stubs: { RouterLink: true },
        },
        ...overrides,
      });
    }
  2. Component interaction — test behaviour, not implementation:

    typescript
    test('calls createTask when form submitted', async () => {
      const wrapper = mountComponent();
      const store = useTaskStore();
    
      await wrapper.find('[data-testid="title-input"]').setValue('New Task');
      await wrapper.find('form').trigger('submit');
    
      expect(store.createTask).toHaveBeenCalledWith(
        expect.objectContaining({ title: 'New Task' }),
      );
    });
  3. Test composables in isolation:

    typescript
    import { createApp } from 'vue';
    
    /** Runs a composable inside a throwaway component context. */
    function withSetup<T>(composable: () => T): [T, ReturnType<typeof createApp>] {
      let result!: T;
      const app = createApp({
        setup() { result = composable(); return () => {}; },
      });
      app.mount(document.createElement('div'));
      return [result, app];
    }
    
    test('useCounter increments', () => {
      const [{ count, increment }] = withSetup(() => useCounter(0));
      expect(count.value).toBe(0);
      increment();
      expect(count.value).toBe(1);
    });
  4. Test Pinia stores independently:

    typescript
    import { setActivePinia, createPinia } from 'pinia';
    
    beforeEach(() => { setActivePinia(createPinia()); });
    
    test('loadTasks populates store', async () => {
      const store = useTaskStore();
      await store.loadTasks();
      expect(store.tasks).toHaveLength(3);
    });
  5. Snapshot testing for complex output:

    typescript
    test('renders task card correctly', () => {
      const wrapper = mountComponent({ props: { task: mockTask } });
      expect(wrapper.html()).toMatchSnapshot();
    });

Feedback Loop — Development Workflow

Critical: Use vue-tsc --noEmit instead of tsc --noEmit for Vue projects. tsc cannot type-check .vue <template> blocks — template errors will be invisible.

PhaseCommandPurpose
TDD / rapid iterationvue-tsc --noEmitType-check templates + scripts — fastest loop
Pre-commiteslint .Static analysis (eslint-plugin-vue required) — zero warnings
Pre-commitprettier --write .Format — non-negotiable
Pre-commitvitest runUnit tests — must all pass
Coverage verificationvitest run --coverageVerify before merging

Rules:

  • Never use tsc --noEmit on Vue projects — it skips all .vue template checking.
  • eslint-plugin-vue must be configured with plugin:vue/vue3-recommended or stricter.
  • prettier must handle .vue files (it does by default).

Anti-Patterns

Quick reference — if you're about to do any of these, stop and use the recommended pattern.

  • ❌ Options API in new code — always use <script setup lang="ts">
  • ❌ Destructuring reactive objects — loses reactivity; use toRefs() or storeToRefs()
  • ❌ Side effects in computed — computed must be pure; use watch or watchEffect
  • ❌ v-if + v-for on the same element — wrap with <template>
  • ❌ :key="index" on dynamic lists — use stable unique IDs
  • ❌ Direct store mutation from components — use store actions
  • ❌ Business logic in <template> — move to computed or composables
  • ❌ tsc --noEmit on Vue projects — use vue-tsc --noEmit (template checking)
  • ❌ ref(null) for template refs in Vue 3.5+ — use useTemplateRef() instead
  • ❌ Verbose modelValue + emit in Vue 3.4+ — use defineModel() instead
  • ❌ Importing API clients directly in stores — inject via inject() for testability
  • ❌ watch for derived state — use computed instead (it's cached and more efficient)

  • Code Idioms and Conventions @.agents/rules/code-idioms-and-conventions.md
  • TypeScript Idioms and Patterns @.agents/skills/typescript-idioms/SKILL.md
  • Project Structure — Vue Frontend @.agents/skills/vue-idioms/references/project-structure.md
  • Frontend Layout (framework-neutral, shared with React) @.agents/skills/frontend-design/references/frontend-layout.md
  • Frontend Design @.agents/skills/frontend-design/SKILL.md
  • Security Principles @.agents/rules/security-principles.md
  • Accessibility Principles @.agents/rules/accessibility-principles.md
  • Architectural Patterns — Testability-First Design @.agents/rules/architectural-pattern.md
  • Testing Strategy @.agents/rules/testing-strategy.md
  • Error Handling Principles @.agents/rules/error-handling-principles.md
  • Logging and Observability Principles @.agents/skills/logging-implementation/SKILL.md

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

Files

SKILL.md and 2 other files (references) in .agents/skills/vue-idioms of irahardianto/awesome-agv.

  • SKILL.md
  • references/project-structure.md
  • references/recommended-dependencies.md

Open the folder on GitHubat commit 9e997ba

Compare with similar skills

Vue Idioms 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 Idioms compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Vue Idioms this skillirahardianto/awesome-agv156—~6kAutomated safety check: PassMIT
Effect TStellahq/opensession394—~3.7kAutomated safety check: PassMIT
Effect TSmattiacerutti/supernova185—~2.8kAutomated safety check: PassMIT
Test Coveragescott-fryxell/brayness125—~1.6kAutomated safety check: PassMIT
Unit Test Vue Piniagithub/awesome-copilot40k1 repos~1.8kAutomated safety check: PassMIT
Effect TSpproenca/dot-skills215—~2kAutomated safety check: PassMIT

Similar skills

  • Effect TS

    tellahq/opensession

    Write idiomatic Effect v4 TypeScript verified against the pinned effect@4.0.0-rc.112 source.

    394 GitHub stars~3.7k tokensUpdated today
    Testing & QAAuto-check passed
  • Effect TS

    mattiacerutti/supernova

    Write idiomatic Effect v4 TypeScript following official best practices from effect-solutions and the Effect source.

    185 GitHub stars~2.8k tokensUpdated yesterday
    DevelopmentAuto-check passed
  • Test Coverage

    scott-fryxell/brayness

    Write Vitest specs for Vue 3 JavaScript (Vite Plus, happy-dom, @vue/test-utils) and analyze V8 coverage + Fallow health to prioritize test-first refactors.

    125 GitHub stars~1.6k tokensUpdated 13 days ago
    Testing & QAAuto-check passed
  • Unit Test Vue Pinia

    github/awesome-copilot

    Official

    Write and review unit tests for Vue 3 + TypeScript + Vitest + Pinia codebases.

    40k GitHub starsUsed in 1 repo~1.8k tokens
    Testing & QAAuto-check passed
  • Effect TS

    pproenca/dot-skills

    Effect-TS library usage in TypeScript — Effect.gen generators, Schema.Struct/Schema.Class definitions, Layer/Context.Tag/Service patterns, Effect.pipe pipelines, Data.TaggedError/Data.Class error…

    215 GitHub stars~2k tokensUpdated 1 mo ago
    DevelopmentAuto-check passed
  • Moves logic out of Astro frontmatter into tested helper modules under shared/lib, with rules for naming, typing, deterministic demo data and sibling test files.

    42k GitHub stars~1.2k tokensUpdated yesterday
    DevelopmentAuto-check passed

More from irahardianto/awesome-agv

All 34 skills in this repo
  • Distinctive Frontend Design Builder

    irahardianto/awesome-agv

    Commits to one bold aesthetic direction, sets up a CSS token system for it, then builds the interface in Vue or plain HTML using those tokens.

    156 GitHub stars~2.4k tokensUpdated 6 days ago
    Auto-check passed
  • Perf Optimization

    irahardianto/awesome-agv

    Profile-driven performance optimization protocol. An agent skill from irahardianto/awesome-agv.

    156 GitHub stars~4.3k tokensUpdated 6 days ago
    Auto-check passed
  • Angular Idioms and Patterns

    irahardianto/awesome-agv

    Coding conventions for Angular 19 and later: standalone components, signals, OnPush change detection, lazy routes and where RxJS still belongs.

    156 GitHub stars~3.8k tokensUpdated 6 days ago
    Auto-check passed
  • CI/CD Pipeline Principles

    irahardianto/awesome-agv

    Rules for designing CI/CD pipelines in layers: universal lint, test and scan stages, container builds with SBOM attestation, and GitOps for orchestrated deployments.

    156 GitHub stars~2.7k tokensUpdated 6 days ago
    Auto-check: notes
  • Hono Idioms

    irahardianto/awesome-agv

    Hono lightweight web framework patterns: type-safe route handlers, middleware composition, Zod validation, and RPC clients for Cloudflare Workers, Node, or Bun.

    156 GitHub stars~3k tokensUpdated 6 days ago
    Auto-check passed
  • Mobile Testing

    irahardianto/awesome-agv

    Mobile E2E testing patterns — Flutter integrationtest, Patrol, Maestro, golden testing, device matrix, and test data management.

    156 GitHub stars~1.8k tokensUpdated 6 days ago
    Auto-check: notes

Questions about Vue Idioms

What does Vue Idioms do?

Vue 3 Composition API patterns: <script setup syntax, reactive state with Pinia stores, reusable composables, and Vitest component testing. Vue Idioms is an agent skill from irahardianto/awesome-agv. Vue 3 Composition API patterns: <script setup syntax, reactive state with Pinia stores, reusable composables, and Vitest component testing.

When should I use Vue Idioms?

Vue Idioms fits situations like: refactoring Vue 3 frontend applications; tasks that involve Unit testing; tasks that involve Refactoring.

How do I install Vue Idioms in Claude Code?

Run `npx skills add irahardianto/awesome-agv --skill vue-idioms -a claude-code`. Or copy the skill folder (.agents/skills/vue-idioms in irahardianto/awesome-agv) into .claude/skills/vue-idioms in your project. Claude Code loads it when a task matches its description.

How do I install Vue Idioms in Codex?

Run `npx skills add irahardianto/awesome-agv --skill vue-idioms -a codex`. Or copy the skill folder (.agents/skills/vue-idioms in irahardianto/awesome-agv) into .agents/skills/vue-idioms in your project. Codex loads it when a task matches its description.

Can I use Vue Idioms 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 irahardianto/awesome-agv --skill vue-idioms -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-idioms, .gemini/skills/vue-idioms, .github/skills/vue-idioms and .opencode/skills/vue-idioms in your project.

What does Vue Idioms need to run?

Going by SKILL.md and its folder, Vue Idioms needs the command-line tools its instructions call (tsc, vitest, eslint and prettier) and credentials named TASK_API_KEY. Our summary lists: A credential in TASK_API_KEY.

Does Vue Idioms 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 Idioms 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 Idioms use?

Vue Idioms 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 Idioms use?

About 6k tokens (SKILL.md is roughly 24k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 2.1k tokens, read only when the agent opens those files.

What are the alternatives to Vue Idioms?

Skills that share tags, products or a category with Vue Idioms: Effect TS (tellahq/opensession, 394 stars), Effect TS (mattiacerutti/supernova, 185 stars), Test Coverage (scott-fryxell/brayness, 125 stars) and Unit Test Vue Pinia (github/awesome-copilot, 40k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Vue Idioms?

irahardianto (a GitHub user) maintains it in irahardianto/awesome-agv, which has 156 GitHub stars. The repository holds 34 skills in this directory. The repository was last updated on October 5, 2026.

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