Files
inkreach-official-website/.agents/skills/vue-pinia-best-practices/reference/state-use-pinia-for-large-apps.md
T

263 lines
6.2 KiB
Markdown

---
title: Use Pinia for Large-Scale Vue Applications
impact: MEDIUM
impactDescription: Hand-rolled reactive stores lack DevTools integration, TypeScript support, and debugging capabilities needed for production apps
type: best-practice
tags: [vue3, pinia, state-management, devtools, architecture, scalability]
---
# Use Pinia for Large-Scale Vue Applications
**Impact: MEDIUM** - While Vue's Composition API allows creating simple reactive stores with `reactive()` and `ref()`, these hand-rolled solutions lack the tooling, conventions, and debugging capabilities needed for large-scale production applications. Pinia is the official Vue state management solution and should be used for any non-trivial application.
## Task Checklist
- [ ] Use Pinia for applications with shared state across multiple components
- [ ] Use Pinia when team collaboration requires consistent patterns
- [ ] Use Pinia when you need Vue DevTools state debugging
- [ ] Hand-rolled `reactive()` is acceptable only for simple, single-developer apps
- [ ] Migrate from Vuex to Pinia (Vuex is in maintenance mode)
## When Hand-Rolled State is Acceptable
Simple reactive state is fine for:
- Prototypes and proof-of-concepts
- Very small applications with minimal shared state
- Single-developer projects with limited scope
- Learning purposes
```javascript
// Simple hand-rolled store - OK for small apps
import { reactive, readonly } from 'vue'
export const store = reactive({
count: 0,
increment() {
this.count++
}
})
```
## When to Use Pinia
Use Pinia when you have any of these requirements:
### 1. DevTools Integration
Pinia provides rich Vue DevTools support:
- Timeline of state changes
- State inspection and editing
- Time-travel debugging
- Action tracking
```javascript
// Pinia store - fully visible in DevTools
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
actions: {
increment() {
this.count++ // Tracked in DevTools timeline
}
}
})
```
### 2. TypeScript Support
Pinia has excellent TypeScript inference:
```typescript
// Full type inference without extra configuration
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({
name: '',
age: 0,
preferences: {
theme: 'light' as 'light' | 'dark'
}
}),
getters: {
// Return type is inferred
displayName: (state) => state.name || 'Anonymous'
},
actions: {
// Full parameter type checking
setUser(name: string, age: number) {
this.name = name
this.age = age
}
}
})
// Usage is fully typed
const userStore = useUserStore()
userStore.name // string
userStore.displayName // string
userStore.setUser('John', 30) // Type-checked
```
### 3. Team Collaboration
Pinia enforces conventions that help teams:
```javascript
// Consistent structure across all stores
// stores/products.js
export const useProductsStore = defineStore('products', {
state: () => ({ /* ... */ }),
getters: { /* ... */ },
actions: { /* ... */ }
})
// stores/cart.js - Same structure
export const useCartStore = defineStore('cart', {
state: () => ({ /* ... */ }),
getters: { /* ... */ },
actions: { /* ... */ }
})
```
### 4. Hot Module Replacement (HMR)
Pinia supports HMR out of the box - state persists during development:
```javascript
// State survives code changes during development
// No need to re-login or re-create state after every edit
```
### 5. Server-Side Rendering (SSR)
Pinia handles SSR state correctly:
```javascript
// Automatic per-request state isolation
// State serialization for hydration
// No cross-request pollution
```
### 6. Plugin Ecosystem
Pinia supports plugins for common needs:
```javascript
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
// Now stores can persist to localStorage
export const useSettingsStore = defineStore('settings', {
state: () => ({
theme: 'light',
language: 'en'
}),
persist: true // Automatically saved/restored
})
```
## Pinia vs Hand-Rolled Comparison
| Feature | Hand-Rolled `reactive()` | Pinia |
|---------|-------------------------|-------|
| DevTools integration | No | Yes |
| TypeScript inference | Manual | Automatic |
| HMR support | No | Yes |
| SSR support | Manual | Built-in |
| Plugins | No | Yes |
| Time-travel debugging | No | Yes |
| Learning curve | Lower | Slightly higher |
| Bundle size | Smaller | ~1KB |
| Team conventions | None | Enforced |
## Migration from Vuex
Vuex is now in maintenance mode. Migrate to Pinia for new features:
```javascript
// Vuex (legacy)
export default createStore({
state: { count: 0 },
mutations: {
INCREMENT(state) { state.count++ }
},
actions: {
increment({ commit }) { commit('INCREMENT') }
}
})
// Pinia (recommended)
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
actions: {
increment() { this.count++ } // No mutations needed!
}
})
```
**Pinia advantages over Vuex:**
- No mutations (simpler mental model)
- Better TypeScript support
- No nested modules complexity
- Smaller bundle size
- Composition API style available
## Pinia Store Styles
Choose the style that fits your team:
### Options Style (Similar to Options API)
```javascript
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
getters: {
double: (state) => state.count * 2
},
actions: {
increment() { this.count++ }
}
})
```
### Setup Style (Composition API)
```javascript
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const double = computed(() => count.value * 2)
function increment() { count.value++ }
return { count, double, increment }
})
```
## Quick Start
```bash
npm install pinia
```
```javascript
// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const app = createApp(App)
app.use(createPinia())
app.mount('#app')
```
## Reference
- [Vue.js - State Management](https://vuejs.org/guide/scaling-up/state-management.html)
- [Pinia Documentation](https://pinia.vuejs.org/)
- [Pinia vs Vuex](https://pinia.vuejs.org/introduction.html#comparison-with-vuex)