Unlock the full potential of your Vue 3 applications with Pinia – the cutting-edge, lightweight state management library.
📦 What is Pinia?
Pinia is the official state management library for Vue 3 (also works with Vue 2). It’s a modern alternative to Vuex — lighter, faster, simpler, and TypeScript-friendly.
- Store and share reactive state across components
- Use getters (computed values)
- Perform actions (async logic, side effects)
- Mutate state directly (no need for mutations like in Vuex)
✨ Key Features
- ✅ Intuitive API
- ✅ TypeScript Friendly
- ✅ DevTools Support
- ✅ Modular Stores
- ✅ Reactivity with Composition API
- ✅ SSR Support
🛠️ How to Install
npm:
npm install pinia
yarn:
yarn add pinia
🔧 Setup in Vue App
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const app = createApp(App)
app.use(createPinia())
app.mount('#app')
🏪 Creating a Store
// stores/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
}),
actions: {
increment() {
this.count++
}
}
})
📥 Using a Store in Components
<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
</script>
<template>
<div>
<p>Count: {{ counter.count }}</p>
<button @click="counter.increment">Increment</button>
</div>
</template>
⚙️ Core Concepts
1. State – your data
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0,
name: 'Pinia Demo',
})
});
2. Getters – like computed properties (readonly)
getters: {
doubleCount: (state) => state.count * 2,
welcomeMessage: (state) => `Welcome to ${state.name}`,
}
3. Actions – like methods (can be async)
actions: {
increment() {
this.count++;
},
async fetchUserData() {
const data = await fetch('/api/user').then(res => res.json());
this.name = data.name;
}
}
4. Mutations?
No need for separate mutations. Directly mutate state in actions or components.
✅ Using Pinia in a Component
<template>
<div>
<p>{{ counter.count }}</p>
<p>{{ counter.doubleCount }}</p>
<button @click="counter.increment">Increment</button>
</div>
</template>
<script setup>
import { useCounterStore } from '@/stores/useCounterStore';
const counter = useCounterStore();
</script>
🔐 Bonus Tips
- Use persistedstate plugin to save state in localStorage
- Use multiple stores to split logic
- Works great with Composition API and
<script setup>
🧠 TL;DR: Pinia vs Vuex
| Feature | Pinia | Vuex |
|---|---|---|
| State | ✅ Reactive | ✅ Reactive |
| Getters | ✅ Like computed() | ✅ Like computed() |
| Mutations | ❌ Not needed | ✅ Required |
| Actions | ✅ Async + direct mutate | ✅ Async supported |
| DevTools | ✅ Integrated | ✅ Integrated |
| TypeScript | ✅ First-class support | 😕 Manual setup |
📊 Pinia vs Vuex vs Redux
| Feature | Pinia 🟢 | Vuex 🟡 | Redux 🔴 |
|---|---|---|---|
| Vue Integration | Official for Vue 3 | Official for Vue 2 & 3 | Needs bindings |
| API Complexity | Simple & Intuitive | Verbose | Very Verbose |
| TypeScript Support | Excellent | Partial | Good |
| Modularity | Fully Modular | Centralized Store | Modular with Toolkit |
| Mutations Required | ❌ No | ✅ Yes | ✅ Yes |
| Reactivity | Vue 3 Reactivity API | Vue Reactivity | Manual handling |
| DevTools | ✅ Yes | ✅ Yes | ✅ Yes |
| Learning Curve | Easy | Moderate | Steep |
| Boilerplate | Low | Moderate | High |
🎯 Benefits of Pinia Over Vuex
- ✅ No need for mutations – use actions directly
- ✅ Simpler syntax and better TypeScript integration
- ✅ Modular store structure by default
- ✅ Better support for Composition API
- ✅ Smaller bundle size
🧩 Basic Function Comparison
| Feature | Pinia | Vuex | Redux |
|---|---|---|---|
| State | state: () => ({ count: 0 }) | state: { count: 0 } | const initialState = {} |
| Getter | getters: { doubleCount } | getters: { doubleCount } | mapStateToProps |
| Action | actions: { increment() } | actions: { increment(ctx) } | dispatch({ type, payload }) |
🧠 Final Thoughts
Pinia is the future of state management in Vue apps! 🚀 It’s lightweight, simple, and powerful — perfect for modern Vue 3 projects.
🔗 Learn More: https://pinia.vuejs.org/
Continue Reading