Introduction
Pinia is the officially recommended state management solution for Vue 3, replacing Vuex. It was designed from the ground up around the Composition API, delivering a simpler API surface, full TypeScript inference, and modular stores that do not require mutations or nested module registration.
What Pinia Does
- Provides reactive stores with state, getters, and actions for Vue 3 and Vue 2 applications
- Offers full TypeScript support with automatic type inference for state and actions
- Integrates with Vue DevTools for state inspection, time-travel debugging, and action tracking
- Supports hot module replacement for stores during development
- Enables code-splitting by importing stores only where they are used
Architecture Overview
Each Pinia store is defined via defineStore() and returns a reactive object. State is a reactive ref, getters are computed properties, and actions are plain methods. Stores are instantiated lazily when first called inside a component or another store. Pinia itself is a Vue plugin that holds the store registry and connects to Vue DevTools. Unlike Vuex, there is no single root store — each store is independent and can reference others directly.
Self-Hosting & Configuration
- Install pinia and register it as a Vue plugin with app.use(createPinia())
- Define stores in individual files for clean code-splitting and tree-shaking
- Use the setup syntax (function-based) or options syntax (object-based) per store
- Enable persistence via pinia-plugin-persistedstate for localStorage or sessionStorage
- Configure SSR hydration by serializing store state on the server and restoring on the client
Key Features
- No mutations: actions directly modify state, eliminating Vuex boilerplate
- Full TypeScript inference without manual type declarations
- Composition API support: use stores inside setup() with reactive destructuring via storeToRefs()
- Plugin system for extending stores with persistence, logging, or undo/redo
- Multiple independent stores with cross-store references and no namespace collisions
Comparison with Similar Tools
- Vuex — Vue's previous official store; requires mutations and modules; Pinia is simpler and fully typed
- Zustand — React-focused minimal store; Pinia is Vue-specific with deeper devtools integration
- MobX — framework-agnostic reactive state; Pinia leverages Vue's reactivity system natively
- Harlem — Vue state management with extensions; Pinia has official Vue team backing
- Effector — multi-framework reactive store; Pinia is tightly optimized for Vue's reactivity
FAQ
Q: Can I migrate from Vuex to Pinia incrementally? A: Yes. Pinia and Vuex can coexist in the same application. Migrate one store at a time by creating a Pinia store and removing the corresponding Vuex module.
Q: Does Pinia work with Vue 2? A: Yes, with the @vue/composition-api package. Pinia supports both Vue 2 and Vue 3 applications.
Q: How do I persist store state across page reloads? A: Use the pinia-plugin-persistedstate plugin. Add it to your Pinia instance and set persist: true in your store definition to sync state with localStorage.
Q: Can stores reference each other? A: Yes. Import and call one store inside another store's action or getter. Pinia handles circular dependencies gracefully through lazy instantiation.