State management is a critical part of building modern front-end applications. If you've worked with Vue 2, you may be familiar with Vuex. But with Vue 3, a new, simpler alternative has emerged: Pinia.
In this article, you’ll learn how to use Pinia to manage application state in a Vue 3 project — from installation to real-world usage.
Enjoy!
🤔 What Is Pinia?
Pinia is the official state management library for Vue 3. It’s lightweight, modular, and built with the Composition API in mind. Compared to Vuex, it offers a simpler syntax, better TypeScript support, and out-of-the-box devtools integration.
Benefits of using Pinia:
- Simpler syntax compared to Vuex
- First-class support for the Composition API
- Built-in devtools and TypeScript support
- Modular design (define as many small stores as needed)
🟢 How to use Pinia in Vue?
1.In your project directory, install Pinia using your favourite package manager:
npm install pinia
2.Then, register it in your main file (usually main.js
or main.ts
):
// 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')
3.Create a simple counter Pinia Store (Stores in Pinia are defined using the defineStore
function):
// stores/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
}),
actions: {
increment() {
this.count++
},
decrement() {
this.count--
}
},
getters: {
doubleCount: (state) => state.count * 2
}
})
Let's take a look at each part of this store file:
-
state
: Returns an object representing the store’s reactive state. -
actions
: Functions that modify the state — like Vue methods. -
getters
: Computed properties based on the state.
4.Using the Store in a Component
<template>
Count: {{ counter.count }}
Double: {{ counter.doubleCount }}
@click="counter.increment">+
@click="counter.decrement">-
template>
<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
script>
Since Pinia stores are reactive, any changes to the state automatically update the UI.
You can also use stores inside composables or other stores — thanks to Vue’s reactivity model.
// useCartStore.js
import { defineStore } from 'pinia'
export const useCartStore = defineStore('cart', {
state: () => ({
items: []
}),
actions: {
addItem(item) {
this.items.push(item)
}
}
})
📖 Learn more
If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this link or by clicking the image below:
It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉
✅ Summary
Pinia is a modern and intuitive state management solution for Vue 3. Whether you're building a small side project or a complex SPA, it gives you everything you need to manage state without unnecessary boilerplate.
Take care and see you next time!
And happy coding as always 🖥️