Pinia is the officially recommended state management library for Vue 3, designed to replace Vuex with a simpler, more intuitive API and first-class TypeScript support. This post covers how to set up Pinia, define stores with state, getters, and actions, how Pinia compares to Vuex, and practical patterns for managing global state in Vue applications.
Pinia
Pinia is a library for storing data in a central location. You won't have to pass it down from component to component. The state is directly accessible to all components. It doesn't matter how deeply nested your components are, the data can be retrieved or updated. Any changes to the data are reflected in all components. This means it's no longer necessary to pass down data through several children components. Data is handled in one centralized location.
Pinia is maintained by the core developers of Vue. You don't have to worry about compatibility issues.
npm install pinia
What is Pinia doing behind the scenes?
Pinia is registering a plugin with the Vue developer tools. The developer tools are completely extendable. The Pinia package will add a new tool for interacting with the state. If you want help with debugging, you should always register the plugin.
Working with State
Let's create a sample js file called modal.js. And then import defineStore function from the pinia package
defineStore function will help us create a new store. We can think of the store as an object that will track the data store inside it. store must be exported from the file, otherwise our components will not have access to the data.
inside defineStore function, we can define state id with object like below:
In object we can add various properties for interacting with our state. Let's add state property
The state object is where we can add our data. Any data we want globally available to other components should be defined here.
We can access the state in another component:
in Header.vue
mapStores function will merge the store into the component, thus giving us access to the state.
And the import our store file also:
And then we can access state value:
As we can access state value by using this.modalStore. Because we created modal state property. For example, if we create user state then we can access this.userStore
Using Getters
There is a way to change a state property inside the store. Just like we can create mutations, we can create something called getters. Getter are exactly what they sound like. They allow you to access a state property from the store. Using a getter is optional. We can access the state property directly through the store object. Pinia offers another solution for retrieving a state property called getters.
The main benefit of using a getter is the support for caching. It can intelligently update itself when the state changes. We know that the computed properties are one way to cache a value. One solution might be to write a computed property for every state property we'd like to use in a given component, that would work. But then we would face duplication issues.
We'd have to define the same computed properties in every component. That's where getters come in. We can think of getters as computed property for our store. One of the main benefits of a getter is that they're accessible to all components. Define a getter once, use it everywhere. Getters are also smart. They will only update if the state changes. This can help with the performance of an application.
in modal.js
in Example.vue
Frequently Asked Questions
What is Pinia?
Pinia is the official state management library for Vue, offering a lightweight alternative to Vuex with a more intuitive API, full TypeScript support without configuration, hot module replacement for stores, and excellent Vue DevTools integration.
What is the difference between Pinia and Vuex?
Pinia has a simpler API with no mutations (only state, getters, and actions), better TypeScript support out of the box, support for multiple stores without nesting, and is the officially recommended choice for new Vue 3 projects over Vuex.

