---
name: pinia-skilld
description: "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."
title: pinia-skilld
canonical_url: https://skilld.dev/gh/skilld-dev/vue-ecosystem-skills/pinia-skilld
last_updated: 2026-09-29T03:26:03.000Z
---

> **Skill from skilld.dev.** Follow the instructions below for this session. You do not need to install anything.
>
> Supporting files, fetch one when the Skill refers to it: [references/api.md](https://skilld.dev/api/skills-raw/skilld-dev/vue-ecosystem-skills/pinia-skilld/references/api.md), [references/diagnostics.md](https://skilld.dev/api/skills-raw/skilld-dev/vue-ecosystem-skills/pinia-skilld/references/diagnostics.md), [references/options-api.md](https://skilld.dev/api/skills-raw/skilld-dev/vue-ecosystem-skills/pinia-skilld/references/options-api.md), [references/plugins.md](https://skilld.dev/api/skills-raw/skilld-dev/vue-ecosystem-skills/pinia-skilld/references/plugins.md), [references/ssr.md](https://skilld.dev/api/skills-raw/skilld-dev/vue-ecosystem-skills/pinia-skilld/references/ssr.md), [references/stores.md](https://skilld.dev/api/skills-raw/skilld-dev/vue-ecosystem-skills/pinia-skilld/references/stores.md), [references/subscriptions.md](https://skilld.dev/api/skills-raw/skilld-dev/vue-ecosystem-skills/pinia-skilld/references/subscriptions.md), [references/testing.md](https://skilld.dev/api/skills-raw/skilld-dev/vue-ecosystem-skills/pinia-skilld/references/testing.md).
>
> If the user asked to install this Skill, run `npx skilld install skilld-dev/vue-ecosystem-skills/pinia-skilld`. Install writes the Skill files into the project, so every session loads them.

# 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

```ts
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].

```ts
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.

```ts
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](https://skilld.dev/api/skills-raw/skilld-dev/vue-ecosystem-skills/pinia-skilld/references/stores.md), [subscriptions](https://skilld.dev/api/skills-raw/skilld-dev/vue-ecosystem-skills/pinia-skilld/references/subscriptions.md).

## 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](https://skilld.dev/api/skills-raw/skilld-dev/vue-ecosystem-skills/pinia-skilld/references/diagnostics.md).
- `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](https://skilld.dev/api/skills-raw/skilld-dev/vue-ecosystem-skills/pinia-skilld/references/api.md): every public export with signatures and type helpers.
- [Stores](https://skilld.dev/api/skills-raw/skilld-dev/vue-ecosystem-skills/pinia-skilld/references/stores.md): state, getters, actions, typing, composing stores, HMR.
- [Subscriptions](https://skilld.dev/api/skills-raw/skilld-dev/vue-ecosystem-skills/pinia-skilld/references/subscriptions.md): `$subscribe`, `$onAction`, `MutationType`, detached and flush options.
- [Plugins](https://skilld.dev/api/skills-raw/skilld-dev/vue-ecosystem-skills/pinia-skilld/references/plugins.md): `pinia.use()`, context, typing extensions, new state and options.
- [SSR](https://skilld.dev/api/skills-raw/skilld-dev/vue-ecosystem-skills/pinia-skilld/references/ssr.md): hydration, `skipHydrate`, per-request pinia, Nuxt.
- [Testing](https://skilld.dev/api/skills-raw/skilld-dev/vue-ecosystem-skills/pinia-skilld/references/testing.md): `setActivePinia`, `@pinia/testing` 2.x usage.
- [Options API](https://skilld.dev/api/skills-raw/skilld-dev/vue-ecosystem-skills/pinia-skilld/references/options-api.md): map helpers without `setup()`.
- [Diagnostics](https://skilld.dev/api/skills-raw/skilld-dev/vue-ecosystem-skills/pinia-skilld/references/diagnostics.md): dev-only `PINIA_R100x` catalog with fixes.

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