All skills
skilld-dev avatar

/pinia-skilld

@b9c39cb

Use when writing, debugging, or refactoring code that imports "pinia", the Vue 3 store library. Covers pinia 4.x: option and setup stores, state, getters, actions, subscriptions, plugins, SSR hydration, testing, Options API map helpers, and v4 nostics diagnostics. Provides version-correct API usage and migration notes from v2 and v3.

Use this Skill: https://skilld.dev/gh/skilld-dev/vue-ecosystem-skills/pinia-skilld

This session only. Nothing lands on disk.

SKILL.md

≈87 tokens always: the name and description. ≈1.4k when used: this file. ≈5.9k more on demand in 8 files.

pinia@4.0.3

Source citations use package-relative paths from the prepared pinia 4.0.3 source: package.json, README.md, dist/pinia.js (runtime), dist/pinia.d.ts (types). Other citations are official documentation URLs.

Requirements

  • Vue ^3.5.11 peer [package.json:62]. Vue 2 is unsupported since v3.
  • @vue/devtools-api ^8.1.5 is a required, non-optional peer [package.json:60-68]. Install it alongside pinia: npm install pinia @vue/devtools-api [README.md:108-111], v4.0.0 release notes.
  • TypeScript >=5.6.0 optional peer [package.json:69-71].
  • ESM-only package: "type": "module", single export . to dist/pinia.js [package.json:42,47-50]. v4 removed CJS resolution; a require() fallback breaks.
  • @pinia/nuxt 1.x and @pinia/testing 2.x are the companion versions for pinia 4 (https://github.com/vuejs/pinia/releases).

Install and setup

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
app.mount('#app')

From [README.md:119-130]. In dev on the client, createPinia() registers the devtools plugin itself [dist/pinia.js:832,847].

Define a store

Two syntaxes. The id is a unique string, first argument in both [dist/pinia.d.ts:645,653].

import { defineStore } from 'pinia'

// Option store: state/getters/actions
export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  getters: {
    doubleCount: (state) => state.count * 2,
  },
  actions: {
    increment() {
      this.count++
    },
  },
})

// Setup store: refs are state, computed are getters, functions are actions
export const useTodos = defineStore('todos', () => {
  const todos = ref<Todo[]>([])
  const done = computed(() => todos.value.filter((t) => t.done))
  function add(todo: Todo) {
    todos.value.push(todo)
  }
  return { todos, done, add }
})

Rules for setup stores [dist/pinia.js:1178-1202]:

  • ref() and reactive() become state.
  • computed() becomes a getter.
  • Functions become actions, wrapped automatically for $onAction.
  • Return every state property. Pinia only picks up returned state, so private state breaks SSR hydration and devtools.

The setup function receives helpers: defineStore('id', ({ action }) => { ... }) [dist/pinia.js:1177, dist/pinia.d.ts:628-638]. action(fn, name?) makes a helper function trackable by $onAction when called within the store. Rarely needed; intended for advanced cases like Pinia Colada.

Use a store

Call useStore() inside setup() (or any composable). Every call returns the same store instance.

const counter = useCounterStore()

counter.count++            // direct state mutation
counter.doubleCount        // getter
counter.increment()        // action

const { count, doubleCount } = storeToRefs(counter) // refs for destructuring

storeToRefs() converts state and getters to refs. It ignores actions and non-reactive properties [dist/pinia.js:1475-1489]. Destructure with it, never plain toRefs() or ...store, when you need reactivity.

Common operations:

  • Group changes into one devtools entry with store.$patch(obj) or $patch(fn). The function form must be synchronous [dist/pinia.d.ts:219-225] and suits array, Map, and Set edits [dist/pinia.js:964-975].
  • $reset() exists only on option stores. On a setup store it throws in dev [dist/pinia.js:1085-1087]; implement your own $reset in the returned object.
  • Assigning store.$state = {...} does not replace state; it calls $patch internally [dist/pinia.js:1207-1216].
  • Declare every state key in state() (or return it from setup), even when the initial value is undefined. New keys added later are not reactive.
  • Outside a component, pass the pinia instance: useStore(pinia). On the server this is mandatory; skipping it risks cross-request state pollution [dist/pinia.js:37-39].

Details: stores, subscriptions.

Version notes and migration

v4.0.0, technically breaking only (https://github.com/vuejs/pinia/releases/tag/v4.0.0):

  • ESM-only distribution.
  • @vue/devtools-api upgraded to v8 and now a required install.
  • Errors and dev warnings refactored onto Nostics diagnostics, codes PINIA_R1001 to PINIA_R1007 [dist/pinia.js:18-56]. See diagnostics.
  • piniaSymbol is now part of the public exports [dist/pinia.js:1491].
  • storeToRefs() skips nullish values gracefully; $subscribe() ignores a duplicate callback instead of stacking a second watcher.

Still relevant from v3.0.0 (https://pinia.vuejs.org/cookbook/migration-v2-v3.html):

  • defineStore({ id: 'x', ... }) object-only signature removed. Use defineStore('x', { ... }).
  • PiniaStorePlugin type removed. Use PiniaPlugin.
  • Vue 2 support dropped. Vue 2 users stay on pinia v2.

Reference files

  • API surface: every public export with signatures and type helpers.
  • Stores: state, getters, actions, typing, composing stores, HMR.
  • Subscriptions: $subscribe, $onAction, MutationType, detached and flush options.
  • Plugins: pinia.use(), context, typing extensions, new state and options.
  • SSR: hydration, skipHydrate, per-request pinia, Nuxt.
  • Testing: setActivePinia, @pinia/testing 2.x usage.
  • Options API: map helpers without setup().
  • Diagnostics: dev-only PINIA_R100x catalog with fixes.

Official docs: https://pinia.vuejs.org

Source: SKILL.md on GitHub

No alerts8d3 checks · Risk SAFE
  • Gen Agent Trust Hub8d

    This skill is a comprehensive documentation and reference set for the Pinia state management library. It consists entirely of markdown files including official guides, changelogs, and mirrored GitHub issues/discussions. No malicious code, exfiltration patterns, or harmful instructions were detected.

  • Socket8d

    No alerts

  • Snyk8d

    Risk: LOW · No issues

Signed by skilld at b9c39cb. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last week.

Activeupdated last week

README badge

README badge for skilld-dev/vue-ecosystem-skills/pinia-skilld