Vue in the Age of AI
AI coding tools write Vue, but without guardrails they miss best practices. Here's how to set up agent skills and a lean AGENTS.md so your AI writes production-ready Vue 3 from the first prompt.
Introduction
Most AI coding tools write Vue, but the output isn't that great. Not because the models are bad, current flagship models like Claude Sonnet 4.7 and GPT-5.5 actually handle Vue 3 reasonably well. The problem is that they don't know the latest best practices for Vue. They'll reach for reactive when separate refs are safer. They might prop drill instead of using Provide/Inject. They'll occasionally generate Options API in a Composition API project. And they don't always create types.
You may be tempted to ignore these things and hope they get caught during code review. But there is a better way. What if you could give your AI the same context a senior Vue developer would have walking into your codebase? In practice you'll need agent skills and a lean AGENTS.md to make this happen. This blog post covers both, plus a code snippet that shows what the output looks like when everything is set up correctly.
If you prefer video format, here's the full walkthrough:
Prerequisites
- Vue 3 project (Nuxt or plain Vue)
- An AI coding assistant that supports agent skills (Claude Code, Kiro, Cursor, or Gemini CLI all work)
- Node.js installed (for the
npxcommands)
Steps
1. Use the Latest Flagship Model
Before anything else, make sure you're on a current flagship model. Alexander Lichter from VoidZero put it plainly: flagship models write solid Vue, but they still need guardrails. If you go with an open-weight or older model you'll probably see even more reactivity mistakes and it will need more correction.
In Kiro, you set the model in the chat box. Pick the latest Claude Sonnet or equivalent.
2. Install Vue Agent Skills
Agent skills are markdown files that give your AI specialized knowledge about a specific library. Think of them as the senior Vue developer's onboarding doc — the patterns, pitfalls, and preferences that take years to internalize, packaged so the AI reads them before every task.
There are three worth knowing about.
vuejs-ai/skills is a community-maintained collection with strong Vue core team involvement. I asked Ben Hong, a Vue core contributor, about this repo — it's the closest we have to an official Vue resource and would be my first choice:
npx skills add vuejs-ai/skills
This installs 8 skills: vue-best-practices, vue-testing-best-practices, vue-router-best-practices, vue-pinia-best-practices, vue-debug-guides, and more. The vue-best-practices skill (v18.0.0) is structured as a 5-phase workflow. The team runs evals across three models (haiku, sonnet, opus) to measure whether the skill actually improves output. That's a level of rigor you don't see in most community resources.
antfu/skills is Anthony Fu's personal collection, with dedicated vue and nuxt skills generated directly from the official Vue and Nuxt docs:
pnpx skills add antfu/skills --skill='*'
Or to install individual skills:
pnpx skills add antfu/skills --skill=vue
pnpx skills add antfu/skills --skill=nuxt
The Vue skill explicitly discourages Reactive Props Destructure outside of <script setup>, a gotcha that trips up models on older codebases. The Nuxt skill has a dedicated Layers section, which matters for the AGENTS.md setup below. Worth noting: antfu's collection also vendors the vue-best-practices skill from vuejs-ai/skills, so if you install both collections you get the same skill once.
skilld takes a different approach. Instead of curated skills you install manually, it generates version-aware skills from your actual package.json dependencies:
npx -y skilld
The interactive wizard reads your project and generates skills for the packages you're actually using. The key problem it solves is that agents have knowledge cutoffs. If you've upgraded to a new version of Nuxt or Pinia, the AI is still working from old patterns. Skilld pulls from docs, release notes, and GitHub issues to generate skills that match your installed versions. You can also search across installed skills: skilld search "useFetch options" -p nuxt.
3. Write a Lean AGENTS.md
Skills handle framework knowledge. Your AGENTS.md handles project-specific conventions — the things that are specific to your codebase, not Vue in general.
Here's what mine looks like for a Vue/Nuxt project:
# Vue Project — AI Rules
## Project
This is a Vue 3 + Nuxt application using TypeScript, Pinia, and Vue Router.
Use Composition API with <script setup lang="ts"> everywhere.
## Vue Standards
- ALWAYS use Composition API with `<script setup lang="ts">` — never Options API
- Prefer `ref` over `reactive` (reactive breaks on reassignment and destructuring)
- Use `shallowRef` for large objects and arrays — do not use deep reactivity when it's not needed
- Never destructure reactive props outside of `<script setup>` — use `toRef` or `toValue` instead. (Vue 3.5+ made destructuring inside `<script setup>` safe via compiler transform, but older patterns and non-setup contexts still lose reactivity.)
- Use `async/await` in composables, never `.then()` chains
- Use `computed` for derived state, never recompute in templates
- Keep components focused: split when a component has more than one clear responsibility
- Props down, events up — make data flow explicit with typed `defineProps` and `defineEmits`
## Nuxt Specifics
- Use Nuxt layers to keep features modular — related components, composables, and stores belong together in a layer
- Keep component files small and scoped so parallel agent work doesn't cause conflicts
- Use Nuxt auto-imports — do not manually import Vue or Nuxt composables
- Use `useFetch` / `useAsyncData` for data fetching, not raw `fetch`
## TypeScript
- TypeScript strict mode always
- Type all props, emits, and composable return values explicitly
- Run `vue-tsc` before declaring a task done — type errors catch AI hallucinations
## Testing & Quality
- Vitest for unit tests — write tests alongside implementation, not after
- ESLint with `vue/recommended` rules
- Run lint and type-check before finishing any task
## Skills
Load these skills for any Vue/Nuxt task:
- vue-best-practices (vuejs-ai/skills)
- nuxt (antfu/skills)
The Nuxt layers rule comes from Daniel Kelly at Vue School. When related components, composables, and stores live together in a layer, the AI can fit the whole feature in context. When code is scattered across a flat structure, the AI has to guess at relationships and makes worse decisions.
The shallowRef rule comes directly from Alexander Lichter and from antfu's skill.
Don't make this file too long. Studies on AI coding context files have found that bloated AGENTS.md files often hurt agent performance. The model has to comb through irrelevant rules to find what applies, and accuracy drops. Keep it under 300 lines. Put your project-specific conventions here, and let the skills handle the framework knowledge. That's why the Skills section at the bottom of the file exists — the AGENTS.md tells the AI which skills to load, and the skills do the heavy lifting.
4. Add Adversarial Code Review
Daniel Kelly recommended the /pr-review-expert skill from skills.sh. After your agent writes code, run this to get a second AI reviewing the first AI's output. It catches things you'd miss when moving fast.
This matters because code reviews become the bottleneck when AI generates code faster than you can read it. Automating the first pass lets you focus on architecture decisions rather than syntax.
5. Demo: One Prompt, Production-Ready Output
Here's what this setup produces in practice. Brand new Vue app, AGENTS.md in place, vue-best-practices skill loaded. One prompt:
Create a composable that fetches a list of GitHub repositories for a given username.
It should handle loading and error states.
This is what came back:
import { ref, shallowRef } from 'vue'
export interface GithubRepo {
id: number
name: string
full_name: string
description: string | null
html_url: string
stargazers_count: number
forks_count: number
language: string | null
updated_at: string
private: boolean
}
export function useGithubRepos() {
const repos = shallowRef<GithubRepo[]>([])
const isLoading = ref(false)
const error = ref<string | null>(null)
async function fetchRepos(username: string): Promise<void> {
if (!username.trim()) {
error.value = 'Username is required'
return
}
isLoading.value = true
error.value = null
try {
const response = await fetch(
`https://api.github.com/users/${encodeURIComponent(username)}/repos?per_page=100&sort=updated`,
{
headers: {
Accept: 'application/vnd.github+json',
'X-GitHub-Api-Version': '2022-11-28',
},
},
)
if (!response.ok) {
if (response.status === 404) throw new Error(`User "${username}" not found`)
if (response.status === 403) throw new Error('GitHub API rate limit exceeded. Try again later.')
throw new Error(`GitHub API error: ${response.status} ${response.statusText}`)
}
const data = await response.json() as GithubRepo[]
repos.value = data
} catch (err) {
error.value = err instanceof Error ? err.message : 'An unexpected error occurred'
repos.value = []
} finally {
isLoading.value = false
}
}
return { repos, isLoading, error, fetchRepos }
}
What the rules and skill produced without being asked:
shallowReffor the array, notref. The repos list could have hundreds of items. Deep reactivity on all of them is wasteful.- Three separate
refs instead ofreactive({ repos, isLoading, error }). Reactive objects break when you destructure them. async/awaitwith afinallyblock.isLoadingresets even if the request fails.- A full
GithubRepoTypeScript interface, unprompted. - Input validation before the async call,
encodeURIComponenton the username, and specific error messages for 404 and 403 (GitHub rate limiting).
Conclusion
The setup is: latest flagship model, vue-best-practices from vuejs-ai/skills, antfu's Vue and Nuxt skills, a lean AGENTS.md with your project conventions, and skilld if you want version-aware skills for your specific dependency versions. Skills handle the framework knowledge so your rules file stays short. One prompt with this in place produces code that would otherwise take several rounds of correction.
Resources:
- vuejs-ai/skills —
npx skills add vuejs-ai/skills - antfu/skills —
pnpx skills add antfu/skills --skill='*' - skilld — version-aware skills from your package.json
- pr-review-expert — adversarial AI code review
- Kiro — AI IDE with built-in skills and steering support