The Official Vue 3 Store
State With Pinia
Pinia is the official Vue 3 state library — type-safe, simpler than Vuex, and built around the Composition API.
What you'll learn
- Install pinia and create a store
- Define state, getters, and actions
- Use a store in a component
Pinia replaces Vuex as Vue’s recommended state library. Stores are essentially composables: refs are state, computeds are getters, functions are actions.
Install & Register
npm i pinia // src/main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
createApp(App).use(createPinia()).mount('#app') Setup-Style Store
The setup syntax is the most natural — it’s just a function that returns reactive state.
// src/stores/counter.ts
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useCounter = defineStore('counter', () => {
const count = ref(0)
const double = computed(() => count.value * 2)
function inc() { count.value++ }
return { count, double, inc }
}) The first argument is the unique store id.
Use It in a Component
<script setup lang="ts">
import { useCounter } from '@/stores/counter'
const counter = useCounter()
</script>
<template>
<p>Count: {{ counter.count }} (double {{ counter.double }})</p>
<button @click="counter.inc">+</button>
</template> Stores are singletons — every component that calls useCounter() shares the same instance. TypeScript inference is automatic from the setup function’s return value.