pinia-skilld

SKILL.md

vuejs/pinia pinia

Intuitive, type safe and flexible Store for Vue

Version: 3.0.4 (Nov 2025) Deps: @vue/devtools-api@^7.7.7 Tags: next: 2.0.0-rc.10 (Sep 2021), beta: 2.1.8-beta.0 (Apr 2024), latest: 3.0.4 (Nov 2025)

References: Docs — API reference, guides

API Changes

This section documents version-specific API changes — prioritize recent major/minor releases.

  • BREAKING: defineStore({ id: 'storeName', ... }) — object signature with id property removed in v3.0.0; use defineStore('storeName', { ... }) instead. Old object syntax silently compiled but is now a runtime error source

  • BREAKING: PiniaStorePlugin type — removed in v3.0.0; use PiniaPlugin instead. Code using PiniaStorePlugin will fail to compile source

  • BREAKING: Vue 2 support dropped in v3.0.0 — Pinia v3 requires Vue 3 only. Users on Vue 2 must stay on Pinia v2 source

  • BREAKING: TypeScript 5 or newer required in v3.0.0 — uses native Awaited type introduced in TS 4.5; TS 5+ recommended source

  • BREAKING: IIFE bundle no longer bundles Vue Devtools in v3.0.0 — devtools API was too large; must be included manually depending on your workflow source

  • BREAKING: Package is now published as type: module in v3.0.0 — CJS dist files still provided but the package root is ESM. May break setups relying on implicit CJS resolution source

  • NEW: action(fn, name?) helper in setup stores — added in v2.2.0, available via SetupStoreHelpers parameter. Wraps a function so it is tracked by $onAction when called within the store; intended for advanced use cases like Pinia Colada source

  • NEW: disposePinia(pinia) — added in v2.1.7, stops the pinia effect scope and removes state, plugins, and stores. Useful in tests or multi-pinia apps; disposed instance cannot be reused source

  • NEW: SetupStoreDefinition<Id, SS> type — added in v2.1.7 for the return type of defineStore() when using a setup function. Extends StoreDefinition and enables better IDE support for setup stores source

  • NEW: mapWritableState now picks up writable computeds in setup stores — added in v2.3.0. Previously only ref state was mapped; WritableComputedRef returns from setup stores are now included source

Also changed: mapGetters DEPRECATED (alias for mapState, still exported) · getActivePinia() returns Pinia | undefined (typed more strictly since v2.0.35) · skipHydrate(obj) stable — skips SSR hydration for non-state objects returned from setup stores · shouldHydrate(obj) exported utility for plugin authors

Best Practices

  • Use $patch() with a function callback rather than an object when mutating arrays or performing multiple related changes — the function form groups all mutations into a single devtools entry and avoids creating intermediate collections source

  • Use $subscribe() instead of watch() on store state — subscriptions fire only once per $patch call regardless of how many individual properties changed, avoiding redundant callbacks when using the function form of $patch source

  • Pass { detached: true } to $subscribe() and true as the second arg to $onAction() when you need listeners to outlive the component — by default both are automatically removed on component unmount source

  • In setup stores, use skipHydrate() to wrap state properties that must not be picked up from SSR initial state (e.g., composables backed by localStorage, client-only refs) — without it, the server's serialized value will override the intended client-side source source

return {
  lastColor: skipHydrate(lastColor), // won't be overwritten by SSR state
  open,
}
  • When a plugin adds new state properties, set the value on both store.$state (for SSR serialization and devtools) and store via toRef(store.$state, 'key') — setting only one breaks devtools display or reactivity sharing source

  • Wrap non-reactive external objects (router, class instances, third-party lib instances) with markRaw() before assigning them in plugins — prevents Vue from trying to deeply observe objects that aren't meant to be reactive source

  • When composing stores that reference each other, place useOtherStore() calls before any await in async actions — after an await the active pinia context may have changed, causing the wrong instance to be returned in SSR source

  • Use createTestingPinia() from @pinia/testing for component tests rather than createPinia() — it stubs all actions by default and makes them inspectable as spies; pass plugins via the plugins option, not via testingPinia.use() source

  • In options store getters, prefer arrow functions that receive state as the first parameter over regular functions using this — arrow function return types are inferred automatically, while this-based getters require an explicit return type annotation source

Weekly Installs
87
GitHub Stars
141
First Seen
Feb 19, 2026
Installed on
github-copilot60
opencode58
codex58
gemini-cli57
claude-code56
amp56