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:

Vue School Link

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 🖥️