Skip to main content
rule

vue-pinia-cursorrules-prompt-file — Cursor rule: how to install

Guides Cursor to write clean Vue 3 and TypeScript state management using Pinia setup stores, proper reactivity, SSR safeguards, and tests.

Install into Cursor · Manually: put the files in place All methods and platforms ↓
.cursor/rules/vue-pinia-cursorrules-prompt-file.mdc
Open on GitHub

What vue-pinia-cursorrules-prompt-file does

This rule targets **/*.ts and **/*.vue files to keep state management organized in Vue 3 projects. It instructs Cursor to generate Pinia stores using Composition API setup syntax under stores/. Every reactive property must be returned so Pinia can track it across devtools and SSR contexts.

Inside components, the prompt enforces storeToRefs() during state and getter destructuring. Without storeToRefs(), component reactivity breaks instantly. Actions remain directly destructurable. The instructions separate server state into tools like Nuxt useFetch or TanStack Query, keeping Pinia reserved for client workflows.

It also restricts persistence: tokens and secrets must never touch browser storage. For testing, it enforces @pinia/testing with complete store resets between runs to prevent cross-test leakage.

What it helps with

  • Structure Vue 3 client state with Pinia setup stores in TypeScript
  • Prevent broken reactivity when destructuring state inside components
  • Separate server API caches from client state management
  • Avoid singleton state leakage across requests in Nuxt and SSR

Example prompts for the agent

  • Generate a stores/cart.ts setup store with typed line items, actions, and pure getters
  • Implement a shopping cart Vue component using storeToRefs() and typed Pinia actions
  • Write unit tests for the cart store actions using @pinia/testing

How to install vue-pinia-cursorrules-prompt-file

Manually: put the files in place

.cursor/rules/vue-pinia-cursorrules-prompt-file.mdc

Frontmatter: description, globs, alwaysApply

Step by step, with commands for each platform: Cursor rules: .mdc files, four modes and what replaced .cursorrules

Questions about vue-pinia-cursorrules-prompt-file

How do I install vue-pinia-cursorrules-prompt-file in Cursor?

Save the rule content to .cursor/rules/vue-pinia-cursorrules-prompt-file.mdc in your repository. Cursor automatically applies it when editing **/*.ts and **/*.vue files.

What does vue-pinia-cursorrules-prompt-file do?

It provides architectural rules for Vue 3 and TypeScript, guiding AI output toward setup stores, pure getters, safe SSR access, and persistence guardrails.

When does the rule recommend against using Pinia?

It advises against putting component-only state or server cache data into Pinia. Local UI state belongs in ref or reactive, while server data belongs in fetch composables or TanStack Query.

Source text

vue-pinia-cursorrules-prompt-file.mdc · CC0-1.0
---
description: "Vue 3 and TypeScript state management guidance for Pinia stores, Composition API usage, SSR, persistence, and testing."
globs: **/*.ts, **/*.vue
alwaysApply: false
---
You are an expert in Vue 3, TypeScript, and Pinia state management.

# Vue + Pinia Guidelines

## State Ownership
- Keep component-only state in the component with `ref`, `reactive`, or `computed`.
- Use Pinia for shared client state that spans routes, layouts, or unrelated component trees.
- Use route params and query strings for shareable navigation state.
- Use Nuxt `useFetch` / `useAsyncData`, TanStack Query for Vue, or the existing API layer for server state.
- Do not copy server cache data into Pinia unless it is an intentional editable draft, offline cache, or workflow snapshot.

## Store Structure
- Prefer setup stores with `defineStore('name', () => { ... })` for Vue 3 Composition API projects.
- Use one store file per domain under `stores/`, such as `stores/cart.ts` or `stores/session.ts`.
- Keep state, computed getters, and actions together when they represent one cohesive domain.
- Return every state property from setup stores so Pinia can track it for devtools, SSR, and plugins.
- Keep getters pure and side-effect free; put writes, I/O, and orchestration in actions.

```ts
import { computed, ref } from 'vue'
import { defineStore } from 'pinia'

interface CartLine {
  id: string
  name: string
  quantity: number
  unitPrice: number
}

export const useCartStore = defineStore('cart', () => {
  const lines = ref<CartLine[]>([])

  const itemCount = computed(() =>
    lines.value.reduce((total, line) => total + line.quantity, 0),
  )

  function addLine(line: CartLine) {
    const existing = lines.value.find((item) => item.id === line.id)
    if (existing) {
      existing.quantity += line.quantity
      return
    }
    lines.value.push(line)
  }

  function clearCart() {
    lines.value = []
  }

  return {
    lines,
    itemCount,
    addLine,
    clearCart,
  }
})
```

## Component Usage
- Call stores at the top of `<script setup>` or inside setup functions, getters, and actions.
- Use `storeToRefs()` when destructuring store state or getters in components.
- Destructure actions directly when useful; actions remain bound to the store.
- Avoid writing large business workflows in components; move them to store actions or composables.
- Prefer computed values over watchers when deriving state.

```vue
<script setup lang="ts">
import { storeToRefs } from 'pinia'
import { useCartStore } from '@/stores/cart'

const cart = useCartStore()
const { itemCount } = storeToRefs(cart)
const { clearCart } = cart
</script>

<template>
  <button type="button" :disabled="itemCount === 0" @click="clearCart">
    Clear cart
  </button>
</template>
```

## TypeScript
- Type store state, action payloads, and API responses explicitly.
- Avoid `any`; use `unknown` and narrow external inputs before committing them to state.
- Use interfaces for object state that is shared across components or API boundaries.
- Prefer discriminated unions for workflow status and error state.
- Keep store IDs stable and descriptive because they appear in devtools and persistence keys.

## Actions and Side Effects
- Actions may be sync or async; keep each action focused on one user or domain workflow.
- Validate action inputs at the boundary before mutating store state.
- Represent async workflows with explicit `status`, `error`, and `lastUpdatedAt` fields when the UI depends on them.
- Reset stale errors before retrying an async action.
- Keep subscriptions, intervals, sockets, and browser listeners outside stores unless the store owns their lifecycle and cleanup.

## SSR, Nuxt, and Router Guards
- In SSR contexts, use the store inside setup, getters, or actions so Pinia can resolve the active app instance.
- When using a store outside setup, such as in a router guard, pass the active Pinia instance if the framework requires it.
- Do not read browser-only storage during server rendering.
- In Nuxt, prefer the Nuxt Pinia integration and SSR-safe composables for data fetching.
- Avoid singleton state leaks across requests by relying on the framework-created Pinia instance.

## Persistence
- Persist only the fields that must survive reloads, such as preferences or incomplete local drafts.
- Never persist secrets, access tokens, refresh tokens, raw PII, or authorization decisions in browser storage.
- Use field allowlists and versioned migrations for persisted store schemas.
- Treat persisted state as untrusted input and validate it before using it for critical workflows.
- Account for hydration timing before rendering UI that depends on persisted values.

## Testing and Tooling
- Use `@pinia/testing` for component tests that need stores.
- Test store actions directly for domain behavior and edge cases.
- Reset Pinia between tests to avoid shared state leakage.
- Add HMR support with `acceptHMRUpdate()` in stores when the project uses Vite HMR patterns.
- Keep stores easy to inspect in Vue Devtools by using clear state names and focused stores.

## Anti-Patterns
- Do not use Pinia as a dumping ground for every reactive value.
- Do not destructure state directly from a store without `storeToRefs()`.
- Do not mutate props or route objects through store actions.
- Do not put server-only objects, request instances, DOM nodes, or timers in store state.
- Do not create circular reads between stores in setup functions; compose stores through actions or computed values instead.

© PatrickJS · CC0-1.0 · PatrickJS/awesome-cursorrules

Similar IDE rules

All IDE rules for Frontend and UI →

From the same set234

The whole set →
webassembly-z80-cellular-automata-cursorrules-prom A Cursor rule that walks the agent through adding a region grid to a Z80 cellular automata simulation built on WebAssembly. ★ 41,024repo stars web-app-optimization-cursorrules-prompt-file Cursor prompt instructions for developing web apps with Svelte 5, SvelteKit, TypeScript, and runes. ★ 41,024repo stars vue3-composition-api-cursorrules-prompt-file This rule guides Cursor on Vue 3 Composition API practices, component setup, and project layout. Use it when you want those conventions reflected in code edits. ★ 41,024repo stars vue A Cursor rule that tells the agent how to write Vue: Composition API, Pinia, typing and routing. Useful when the project already has .vue and .ts files. ★ 41,024repo stars vue-claude-stack This rule guides code generation for Vue 3 and Nuxt 3, covering Composition API, TypeScript, and Pinia. Use it to give an agent consistent project conventions. ★ 41,024repo stars vue-3-nuxt-3-typescript-cursorrules-prompt-file A Cursor rule that tells the agent how to write Vue 3 and Nuxt 3 code: Composition API, TypeScript interfaces, Nuxt conventions. Useful when the project already runs this stack. ★ 41,024repo stars vue-3-nuxt-3-development-cursorrules-prompt-file Directs Cursor to follow Vue 3 and Nuxt 3 practices. Requires planning via pseudocode first, uses the Composition API, and relies exclusively on TailwindCSS. ★ 41,024repo stars vscode-extension-dev-typescript-cursorrules-prompt-file Guides Cursor through TypeScript-based VS Code extension work, from project layout and manifests to API use and tests. ★ 41,024repo stars

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor