Intuitive, type safe and flexible Store for Vue
npx @tessl/cli install tessl/npm-pinia@3.0.0Pinia is a modern state management library for Vue.js applications that provides an intuitive, type-safe, and flexible store system. It serves as the official successor to Vuex, offering better TypeScript integration, composition API support, and modular design with automatic type inference.
npm install piniaimport { createPinia, defineStore, storeToRefs } from "pinia";For CommonJS:
const { createPinia, defineStore, storeToRefs } = require("pinia");import { createApp } from "vue";
import { createPinia, defineStore } from "pinia";
// Create and install Pinia
const app = createApp({});
const pinia = createPinia();
app.use(pinia);
// Define a store with composition API
const useCounterStore = defineStore("counter", () => {
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
function increment() {
count.value++;
}
return { count, doubleCount, increment };
});
// Define a store with options API
const useUserStore = defineStore("user", {
state: () => ({
name: "John Doe",
email: "john@example.com",
}),
getters: {
displayName: (state) => `${state.name} (${state.email})`,
},
actions: {
updateName(newName: string) {
this.name = newName;
},
},
});
// Use the store in a component
const counter = useCounterStore();
const user = useUserStore();
counter.increment();
user.updateName("Jane Doe");Pinia's architecture consists of several key components:
createPinia()defineStore() supporting both options and setup syntaxCore functions for creating and managing the global Pinia instance that coordinates all stores in your application.
function createPinia(): Pinia;
function disposePinia(pinia: Pinia): void;
function setActivePinia(pinia: Pinia): void;
function getActivePinia(): Pinia | undefined;
interface Pinia {
install(app: App): void;
use(plugin: PiniaPlugin): Pinia;
state: Ref<Record<string, StateTree>>;
_p: PiniaPlugin[];
_a: App | null;
_e: EffectScope;
_s: Map<string, StoreGeneric>;
}Functions for defining stores with both composition API (setup function) and options API syntax, providing flexible patterns for different development preferences.
function defineStore<Id extends string, S extends StateTree, G extends _GettersTree<S>, A>(
id: Id,
options: Omit<DefineStoreOptions<Id, S, G, A>, 'id'>
): StoreDefinition<Id, S, G, A>;
function defineStore<Id extends string, SS>(
id: Id,
storeSetup: () => SS,
options?: DefineSetupStoreOptions<Id, _ExtractStateFromSetupStore<SS>, _ExtractGettersFromSetupStore<SS>, _ExtractActionsFromSetupStore<SS>>
): StoreDefinition<Id, _ExtractStateFromSetupStore<SS>, _ExtractGettersFromSetupStore<SS>, _ExtractActionsFromSetupStore<SS>>;
interface DefineStoreOptions<Id extends string, S extends StateTree, G extends _GettersTree<S>, A> {
id: Id;
state?: () => S;
getters?: G & _GettersTree<S>;
actions?: A & _ActionsTree;
}Utilities for working with store instances including extracting reactive references, hydration control, and hot module replacement support.
function storeToRefs<SS extends StoreGeneric>(store: SS): StoreToRefs<SS>;
function skipHydrate<T = any>(obj: T): T;
function shouldHydrate(obj: any): boolean;
function acceptHMRUpdate(store: StoreDefinition, hot: any): (newStore: StoreDefinition) => any;
type StoreToRefs<SS extends StoreGeneric> = {
[K in keyof SS as SS[K] extends (...args: any[]) => any ? never : K]: SS[K] extends Ref
? SS[K]
: Ref<SS[K]>;
};Map helper functions that provide compatibility with Vue's Options API, allowing stores to be mapped to component computed properties and methods.
function mapStores<Stores extends any[]>(...stores: [...Stores]): _Spread<Stores>;
function mapState<Id extends string, S extends StateTree, G extends _GettersTree<S>, A, Keys extends keyof (S & G)>(
useStore: StoreDefinition<Id, S, G, A>,
keys: readonly Keys[]
): _MapStateReturn<S & G, Keys>;
function mapWritableState<Id extends string, S extends StateTree, G extends _GettersTree<S>, A, Keys extends keyof S>(
useStore: StoreDefinition<Id, S, G, A>,
keys: readonly Keys[]
): _MapWritableStateReturn<S, Keys>;
function mapGetters<Id extends string, S extends StateTree, G extends _GettersTree<S>, A, Keys extends keyof G>(
useStore: StoreDefinition<Id, S, G, A>,
keys: readonly Keys[]
): _MapStateReturn<G, Keys>;
function mapActions<Id extends string, S extends StateTree, G extends _GettersTree<S>, A, Keys extends keyof A>(
useStore: StoreDefinition<Id, S, G, A>,
keys: readonly Keys[]
): _MapActionsReturn<A, Keys>;
function setMapStoreSuffix(suffix: string): void;type StateTree = Record<PropertyKey, any>;
interface Store<Id extends string = string, S extends StateTree = {}, G = {}, A = {}> {
$id: Id;
$state: UnwrapRef<S>;
$patch(partialState: _DeepPartial<UnwrapRef<S>>): void;
$patch<F extends (state: UnwrapRef<S>) => any>(stateMutator: ReturnType<F> extends Promise<any> ? never : F): void;
$reset(): void;
$subscribe(callback: SubscriptionCallback<S>, options?: { detached?: boolean } & WatchOptions): () => void;
$onAction(callback: StoreOnActionListener<Id, S, G, A>, detached?: boolean): () => void;
$dispose(): void;
}
type StoreDefinition<Id extends string = string, S extends StateTree = {}, G = {}, A = {}> = () => Store<Id, S, G, A>;
type PiniaPlugin = (context: PiniaPluginContext) => Partial<PiniaCustomProperties & PiniaCustomStateProperties> | void;
interface PiniaPluginContext<Id extends string = string, S extends StateTree = {}, G = {}, A = {}> {
pinia: Pinia;
app: App;
store: Store<Id, S, G, A>;
options: DefineStoreOptionsInPlugin<Id, S, G, A>;
}
enum MutationType {
direct = 'direct',
patchObject = 'patch object',
patchFunction = 'patch function',
}