Pinia: The Intuitive Store for Vue
Pinia is an intuitive, type-safe, and flexible state management library specifically designed for Vue.js applications. It serves as a lightweight and robust alternative to Vuex, leveraging Vue 3's Composition API for a more modern and streamlined development experience. The current stable major version is v3.x, with the latest release being v3.0.4, indicating active maintenance and minor updates within the major release. Pinia distinguishes itself through its excellent TypeScript support, providing strong type inference out-of-the-box, automatic module generation (no need for nested modules), and a plugin system. Its API is designed to be straightforward and familiar to Vue developers, making state management less verbose and more declarative. Releases within a major version (like v3.0.x) typically include bug fixes and minor improvements, with major version bumps (v2 to v3) often aligning with Vue major version releases and dropping support for older ecosystems (e.g., Vue 2).
Common errors
-
TypeError: Cannot read properties of undefined (reading 'install')
cause Pinia (or another plugin) was not installed correctly with `app.use()`.fixEnsure `app.use(createPinia())` is called correctly on your Vue application instance before mounting. -
Error: [pinia]: Missing Pinia plugin. Ensure 'app.use(createPinia())' is called.
cause Attempting to use `defineStore` or `useMyStore` composables before Pinia has been installed on the Vue application.fixAdd `app.use(createPinia())` to your application's entry point before any component using Pinia is initialized. -
Type 'T' does not satisfy the constraint 'object'.
cause TypeScript version is older than 4.5.0, which is required by Pinia v3.0.0 for its use of the `Awaited` utility type.fixUpgrade TypeScript to version 4.5.0 or higher in your project dependencies (`npm install -D typescript@latest`).
Warnings
- breaking Pinia v3.0.0 drops support for Vue 2. If you are using Vue 2, you must remain on Pinia v2.x.
- breaking Pinia v3.0.0 requires TypeScript version >=4.5.0 due to its internal use of the native `Awaited` type. Projects with older TypeScript versions will encounter compilation errors.
- breaking The `PiniaStorePlugin` API has been removed in Pinia v3.0.0. Developers using custom plugins need to adapt to the new plugin system, which likely involves using `PiniaPlugin`.
- gotcha Ensure `app.use(pinia)` is called *before* you try to access any stores within your components' `setup` functions or lifecycle hooks, otherwise stores will not be available.
Install
-
npm install pinia -
yarn add pinia -
pnpm add pinia
Imports
- createPinia
const { createPinia } = require('pinia');import { createPinia } from 'pinia' - defineStore
import defineStore from 'pinia';
import { defineStore } from 'pinia' - Store
import type { Store } from 'pinia' - useStore
import { useStore } from 'pinia';import { useMyStore } from './stores/myStore'
Quickstart
import { createApp } from 'vue';
import { createPinia, defineStore } from 'pinia';
const app = createApp({
template: `
<div>
<h1>Counter: {{ counter }}</h1>
<p>Double Counter: {{ doubleCounter }}</p>
<button @click="increment">Increment</button>
<button @click="reset">Reset</button>
</div>
`,
setup() {
const main = useMainStore();
return {
counter: main.counter,
doubleCounter: main.doubleCounter,
increment: main.increment,
reset: main.reset
};
}
});
// Define a Pinia store
const useMainStore = defineStore('main', {
state: () => ({
counter: 0,
name: 'Pinia Example'
}),
getters: {
doubleCounter: (state) => state.counter * 2
},
actions: {
increment() {
this.counter++;
},
reset() {
this.counter = 0;
}
}
});
const pinia = createPinia();
app.use(pinia);
app.mount('#app');
// To make it runnable in a simple environment, assume an #app div exists:
document.body.innerHTML = '<div id="app"></div>';