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.

referencesstores.md

≈997 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Stores: state, getters, actions

Option stores

export const useStore = defineStore('storeId', {
  state: () => ({ count: 0, items: [] as Item[] }),
  getters: { double: (state) => state.count * 2 },
  actions: {
    increment() {
      this.count++
    },
  },
})
  • state must be an arrow function returning a fresh plain object. Class instances trigger PINIA_R1003 [dist/pinia.js:1294].
  • Declare every state key in state(), even undefined initial values. Keys added later do not become reactive. https://pinia.vuejs.org/core-concepts/state.html
  • For empty lists or unloaded data, cast: items: [] as Item[], user: null as User | null.
  • Option stores support $reset() [dist/pinia.js:1079-1084].

Setup stores

export const useStore = defineStore('storeId', ({ action }) => {
  const count = ref(0)
  const items = ref<Item[]>([])
  const double = computed(() => count.value * 2)
  function increment() { count.value++ }
  return { count, items, double, increment }
})
  • Refs and reactives become state, computeds become getters, functions become actions [dist/pinia.js:1178-1202].
  • Return all state. Hidden state breaks SSR, devtools, and plugins.
  • $reset() throws on setup stores in dev [dist/pinia.js:1085-1087]. Return your own $reset:
    const count = ref(0)
    function $reset() { count.value = 0 }
    return { count, $reset }
  • The { action } helper parameter tracks internal helper functions with $onAction [dist/pinia.d.ts:628-638]. Rarely needed.
  • Custom options for plugins go in the third argument:
    defineStore('search', () => { ... }, { debounce: { searchContacts: 300 } })

Getters

  • Prefer arrow functions receiving state; return types are inferred.
  • To use other getters or this, write a method and annotate the return type explicitly:
    getters: {
      double: (state) => state.count * 2,
      doublePlusOne(): number {
        return this.double + 1
      },
    }
  • A getter name colliding with a state name triggers PINIA_R1002 [dist/pinia.js:1010-1013].
  • Writable computed returned from a setup store stays writable on the store, in storeToRefs(), and in mapWritableState [dist/pinia.d.ts:313,852].

Actions

  • Actions can be async. this is the store instance.
  • Like composables, they can use any Vue or third-party composable.
  • Errors propagate to the caller; $onAction listeners observe them via onError.

Mutating state

store.count++
store.$patch({ count: 1, name: 'x' })
store.$patch((state) => {
  state.items.push({ name: 'shoes', quantity: 1 })
})
  • $patch groups changes into one devtools entry.
  • The function form must be synchronous [dist/pinia.d.ts:219-225]. Use it for arrays, Maps, and Sets; the object form merges them recursively [dist/pinia.js:964-975].
  • store.$state = newObj does not replace state; it patches [dist/pinia.js:1207-1216].
  • You cannot replace the whole pinia.state.value[store.$id] and keep reactivity; patch instead. https://pinia.vuejs.org/core-concepts/state.html

Composing stores

Call other stores inside actions or setup:

const useUserStore = defineStore('user', () => { ... })

export const useCartStore = defineStore('cart', () => {
  const user = useUserStore()
  // ...
})

In async actions that reference another store, call useOtherStore() before any await. After an await the active pinia can differ on the server, returning the wrong instance. https://pinia.vuejs.org/cookbook/composing-stores.html

Hot module replacement

const useUser = defineStore('user', () => { ... })

if (import.meta.hot) {
  import.meta.hot.accept(acceptHMRUpdate(useUser, import.meta.hot))
}

[dist/pinia.d.ts:920-935]. Works in Vite-like environments; production builds no-op it [dist/pinia.js:908-909]. Changing the store id during HMR reports PINIA_R1005 and reloads the module [dist/pinia.js:917-924]. https://pinia.vuejs.org/cookbook/hot-module-replacement.html

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

  • Snyk9d

    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