Developing Pinia Stores
When to use this skill
Use this skill when you need to:
- •Create new Pinia stores for state management
- •Define store state, getters, and actions
- •Compose multiple stores together
- •Integrate stores with Vue components
- •Handle async operations in stores
- •Refactor stores for better type safety or structure
Store File Structure
- •
storeName.ts: Store definition with state, getters, and actions - •Place stores in
stores/directory (e.g.,stores/user.ts,stores/cart.ts) - •Use
use<Name>Storenaming convention (e.g.,useUserStore,useCartStore)
Instructions
Creating a New Store
Follow these steps to create a new Pinia store:
- •
Create store file:
stores/storeName.ts - •
Define the store using Setup Store pattern:
- •Import
defineStorefrom Pinia - •Import
ref,computedfrom Vue - •Define state as
ref()values - •Define getters as
computed()properties - •Define actions as plain functions
- •Return all public state, getters, and actions
- •See setup-stores.md for patterns
- •Import
- •
Add TypeScript types:
- •Type all state refs explicitly
- •Let TypeScript infer computed types when possible
- •Type action parameters and return values
- •See typescript.md for patterns
- •
Handle async operations (if needed):
- •Add loading/error state refs
- •Use try/catch/finally in async actions
- •Clean up state appropriately
Modifying an Existing Store
- •
Understand current state:
- •Review existing state, getters, and actions
- •Identify dependencies on other stores
- •
Make changes:
- •Add/modify state refs as needed
- •Update getters if derived state changes
- •Update actions for new behavior
- •Ensure all new exports are returned
- •
Update consumers:
- •Check components using the store
- •Update destructuring if new state/actions added
- •Verify reactivity is preserved
Using Stores in Components
vue
<script setup lang="ts">
import { useCounterStore } from '@/stores/counter'
import { storeToRefs } from 'pinia'
const store = useCounterStore()
// Destructure reactive state/getters with storeToRefs
const { count, doubleCount } = storeToRefs(store)
// Actions can be destructured directly
const { increment, reset } = store
</script>
Quality Checklist
Before completing work on any store, verify:
- • Store uses Setup Store pattern (not Options API)
- • All state is typed explicitly
- • Getters use
computed()for reactivity - • Async actions have loading/error handling
- • No circular dependencies between stores
- • Store is properly exported and named (
use<Name>Store) - • Components use
storeToRefs()for destructuring state
Best Practices
Naming:
- •Store IDs: lowercase with hyphens (
'user-settings') - •Store functions:
use<Name>Storepattern (useUserSettingsStore) - •State: descriptive nouns (
items,currentUser,isLoading) - •Getters: descriptive, often prefixed with
is/has/get(isLoggedIn,totalItems) - •Actions: verbs describing the action (
fetchUser,addItem,reset)
State Management:
- •Keep stores focused on a single domain
- •Prefer multiple small stores over one large store
- •Use
shallowRef()for large objects that don't need deep reactivity - •Initialize state with sensible defaults
Composition:
- •Access other stores inside actions/getters, not at setup level
- •Avoid circular dependencies between stores
- •Use composables for shared logic
- •See composables.md for patterns
Type Safety:
- •Always type state refs explicitly
- •Export store return type for consumers
- •Avoid
anyandunknowntypes - •See typescript.md for patterns
Note:
- •For detailed patterns and examples, consult the reference documentation in the
references/directory. - •Starter template is available in the
assets/directory.