Cursor Rules for Vue: Components, State, and Tests
Cursor rules for Vue that cover component API conventions, reactivity patterns, state ownership, and test requirements, with fenbs keeping the product decisions and naming conventions that should survive a model change.
Updated 4 min read
Cursor rules for Vue define which composition API patterns your project uses, how components expose their props and emits, where state lives, and what tests cover a component before it is done. Without them, an assistant mixes Options API and Composition API, creates redundant state stores, and skips test coverage that your team has agreed on.
fenbs keeps the product decisions behind the conventions: which Pinia stores own which data, why a specific component API was chosen, and the current state of features still in development. The rule sets the style; fenbs keeps the reasoning.
What Vue rules should specify
Vue 3 gives assistants multiple valid approaches for the same task. Both the Options API and the Composition API work. Props can be defined with type annotations or with defineProps. State can live in the component or in a Pinia store. A rule that names the approach your project uses removes those choices and lets the assistant focus on the actual task.
- API style: Composition API with
<script setup>only, or whether Options API components still exist in the codebase. - Props and emits: how to define them and whether runtime or type-only definitions are preferred.
- State ownership: which Pinia stores exist, what each owns, and when a component may use local
reforreactive. - Component naming: PascalCase for single-file components, and the folder structure.
- Test coverage: which test types are required and the commands to run.
Composition API and script setup
Vue 3's <script setup> is the recommended approach for new components, but many codebases still have Options API components from a migration. An assistant without guidance will use whichever it encounters first. A rule that states your current standard prevents new components from using the old pattern.
Within Composition API, small choices matter. Should defineProps use type-only syntax or runtime declarations? Should ref or reactive be preferred for local state? These are low-stakes decisions individually but create visual inconsistency when they vary across a codebase. A short rule resolves them permanently.
---
description: Vue component and state conventions
globs: "**/*.vue,src/stores/**/*.ts"
alwaysApply: false
---
## API style
- Use Composition API with `<script setup>` for all new components.
- Do not convert existing Options API components unless that is the task's purpose.
## Props and emits
- Define props with TypeScript type-only syntax: `defineProps<{ label: string }>()`.
- Define emits with `defineEmits<{ change: [value: string] }>()`.
## State
- Global state lives in Pinia stores under `src/stores/`. Check existing stores before creating a new one.
- Use `ref` for primitives and `reactive` for objects in component-local state.
- Do not access store state directly from a template; map it through a computed property.
## Components
- PascalCase filename: `UserProfile.vue`, not `user-profile.vue`.
- One component per file; no inline component definitions.
## Tests
- Unit tests use Vitest and Vue Test Utils.
- Every new component needs at least one test that renders it and checks a key output.
- Run `pnpm test` before marking a task done.State ownership with Pinia
Store granularity is a decision that is hard to change later. A store that owns too much becomes a coordination bottleneck; a store that owns too little creates boilerplate for every component that needs related data. Recording the store inventory and ownership rules in fenbs means future sessions start from the considered design rather than re-examining the question each time.
Pinia makes it easy to create new stores, which means an assistant can create one for every feature rather than checking whether existing stores already own the relevant data. A rule that lists the stores and their responsibilities helps the assistant add state to the right place and use the composition that already exists.
When a store does not exist yet, the rule can define the process: create the store in src/stores/, follow the naming convention, and record the new store's ownership in fenbs. That keeps the store inventory legible over time.
Reactivity pitfalls
Vue's reactivity system works through Proxy objects. Destructuring a reactive object loses reactivity. Returning a reactive object from a composable and then destructuring it in the component has the same problem. A rule that names these pitfalls, or refers the assistant to the project's composable conventions, prevents subtle reactivity bugs that can be hard to trace.
Composables that return reactive state require the same care. A composable that returns a raw reactive object and is then destructured at the call site loses its reactivity, which can produce components that render stale data without a visible error. A rule that states "composables return ref values or a non-destructured reactive object" removes ambiguity and gives the assistant a pattern to follow consistently.
The toRef and toRefs helpers exist precisely for this: they convert a reactive object's properties back into individual ref values that stay connected to the original. When a rule names them, the assistant uses them correctly rather than reaching for a workaround that breaks reactivity in a less obvious way.
The Vue 3 documentation at vuejs.org (opens in a new tab) explains the rules for reactive objects in detail. The rule file can reference it for the general case and state any project-specific convention on top.
Keep product and API decisions across sessions
When the team agrees on a new Pinia store boundary, approves a change to a public component API, or decides how composables should be shared across features, record it in fenbs as a Decision. The assistant reads those decisions before working on state or component APIs. The rule holds the current conventions; decisions explain the choices that shaped them and the reasons a future session should not undo them. fenbs does not run Vue tests; it keeps the record of what was agreed.
Create a free accountFree for one person · No credit card · Works with Claude, ChatGPT, Cursor and more
How to set up Vue rules with fenbs
- Create a free account and add your Vue project.
- Record the key decisions in fenbs: which Pinia stores exist and what each owns, any approved exceptions to the Composition API rule, and naming conventions for composables.
- Place the
.cursor/rules/vue.mdcfile at the project root and adjust the store path and test command to match your setup. - Connect Cursor via Integrations and ask it to read the project context before working on any state or component task.
- When a task reveals a new store ownership pattern or a composable convention, add it to the rule and record the decision in fenbs.
For more component and framework rule patterns, see cursor rules examples and cursor rules for AI projects. For organizing multiple rule files, see cursor rules hierarchy and cursor rules globs. For comparing Cursor with other editors, see Cursor vs VS Code.