Pinia stores, Vue 3 state patterns. Use when managing client state in Vue applications, choosing between Options/Setup stores, composing stores, or implementing persistence.
Quick Guide: Use Pinia for all shared client state in Vue 3. Options stores for simplicity, Setup stores for flexibility. Server data? Use your data fetching solution. Use
storeToRefs()when destructuring state.
<critical_requirements>
(You MUST use a data fetching solution for ALL server/API data - NEVER put API responses in Pinia stores)
(You MUST use storeToRefs() when destructuring state from stores - direct destructuring loses reactivity)
(You MUST return ALL state properties in Setup stores - private state breaks SSR and DevTools)
(You MUST use named exports ONLY - NO default exports in any store files)
(You MUST use named constants for ALL numbers - NO magic numbers in state code)
<philosophy> </philosophy> <patterns> </patterns></critical_requirements>
Auto-detection: Pinia, defineStore, Vue 3 state, storeToRefs, Vue state management, Options store, Setup store
When to use:
When NOT to use:
ref() or reactive())Pinia is the official state management solution for Vue 3, designed to be intuitive, type-safe, and flexible. It eliminates the boilerplate of Vuex while maintaining powerful features like DevTools integration, plugin support, and SSR compatibility.
Core Principles:
<script setup>State Ownership:
| State Type | Solution | Reason |
|---|---|---|
| Server/API data | Data fetching solution | Caching, synchronization, loading states |
| Shared client state | Pinia | Reactivity, DevTools, persistence |
| Component-local state | ref() / reactive() | Simpler, no overhead |
| URL state (filters) | Route query params | Shareable, bookmarkable |
Pinia offers two store definition syntaxes. Choose based on your needs.
Which store syntax should I use?
Need composables (useRoute, useI18n)?
├─ YES → Setup Store
└─ NO → Need watchers inside store?
├─ YES → Setup Store
└─ NO → Prefer Vue Options API style?
├─ YES → Options Store
└─ NO → Setup Store (more flexible)
Options Store: Simpler, familiar to Vuex users, built-in $reset() method
Setup Store: More flexible, supports composables, requires manual reset
For implementation examples, see examples/core.md.
Use Options stores for straightforward state management with familiar syntax.
$reset() method is neededFor implementation examples and good/bad comparisons, see examples/core.md.
Use Setup stores when you need maximum flexibility and composable integration.
useRoute, useRouter)useI18n)ref() for state, computed() for getters$reset() if neededFor implementation examples, see examples/core.md.
Proper store access patterns prevent reactivity issues.
storeToRefs() for state/getters - preserves reactivityFor implementation examples with storeToRefs, see examples/core.md.
Stores can use other stores, but follow rules to avoid circular dependencies.
For implementation examples, see examples/core.md.
Use plugins for persisting state across sessions.
pinia-plugin-persistedstate for most casespick option to persist specific properties onlyFor implementation examples, see examples/persistence.md.
Extend all stores with shared functionality.
For implementation examples, see examples/plugins.md.
Test stores in isolation and within components.
setActivePinia()createTestingPinia() for component mounting@pinia/testingFor implementation examples, see examples/testing.md.
Handle server-side rendering and hydration properly.
typeof window !== "undefined" checksFor implementation examples, see examples/ssr.md.
<red_flags>
High Priority Issues:
storeToRefs() - silently breaks reactivity, UI shows stale datalocalStorage, window) - crashes SSRGotchas & Edge Cases:
storeToRefs() works for state and getters only, not actions - destructure actions directly$reset(), Setup stores do not - implement manually or use a plugin$patch with a function allows accessing current state: store.$patch(state => { state.items.push(item) })this - use function keyword or state parameterFor complete anti-pattern examples, see reference.md.
</red_flags>
Detailed Resources:
<critical_reminders>
(You MUST use a data fetching solution for ALL server/API data - NEVER put API responses in Pinia stores)
(You MUST use storeToRefs() when destructuring state from stores - direct destructuring loses reactivity)
(You MUST return ALL state properties in Setup stores - private state breaks SSR and DevTools)
(You MUST use named exports ONLY - NO default exports in any store files)
(You MUST use named constants for ALL numbers - NO magic numbers in state code)
Failure to follow these rules will cause reactivity bugs, SSR hydration errors, and DevTools failures.
</critical_reminders>