Pinia integrates fully with Vue DevTools. This episode covers how to inspect state and actions per store, the time-travel feature, and troubleshooting common problems: non-reactive state caused by destructuring, undetected changes, and circular store dependencies.

Debugging state management without DevTools is like finding a needle in a haystack. Fortunately, Pinia integrates fully with Vue DevTools — every store, state, getter, and action shows up there, complete with the time-travel feature for replaying changes.
Episode 10 covers two things: getting the most out of Vue DevTools, and troubleshooting the most common problems Pinia developers face. After this episode, you'll have a systematic debugging workflow.
Vue DevTools shows a separate Pinia tab for all the app's stores. Inside it you can see:
Make sure the Vue DevTools extension is active and the project is running in development mode. If the Pinia tab doesn't appear, restart the app after Pinia is installed in main.ts.
DevTools' flagship feature is time-travel — replaying the sequence of state mutations:
npm run devWhile the app is running, open the DevTools panel, the Pinia tab, and run a few actions. In the mutation list section, you can click an earlier point in time — the entire state will return to its state at that moment. This is very useful for finding which action caused a bug.
Besides DevTools, Pinia provides the $onAction API to listen to every action call from within code. This is useful when a bug only appears in a specific environment and you want to record its trace:
store.$onAction(({ name, args, after, onError }) => {
console.log(`action ${name} called`, args)
after((result) => {
console.log(`${name} finished`, result)
})
onError((error) => {
console.error(`${name} failed`, error)
})
})store.$onAction({...}) receives a callback with information about the action name, arguments, the after hook, and the onError hook. If this pattern reminds you of $subscribe in episode 13, you guessed right — $subscribe monitors state changes, while $onAction monitors store method calls.
The most common problem in Pinia: the UI never changes even though the state was changed. The cause is almost always ordinary destructuring:
// WRONG: copies the value, not a reactive reference
const { count } = useCounterStore()
// RIGHT: take refs that stay connected
const { count } = storeToRefs(useCounterStore())const { count } = useCounterStore() just copies the number — changes in the store won't be seen. Replace it with storeToRefs(useCounterStore()) so count becomes a live ref.
If an assignment like store.items.push(...) doesn't trigger a re-render, check whether the object being written is truly reactive state, not a copy:
// WRONG: a new array outside the store
const baru = [...store.items, item]
store.items = baru
// RIGHT: mutate directly with a patch function
store.$patch((state) => {
state.items.push(item)
})store.$patch((state) => state.items.push(item)) ensures the mutation happens inside reactive state, so DevTools and subscribers detect it too.
Two stores that use each other can cause errors in DevTools:
// stores/a.ts uses useBStore, stores/b.ts uses useAStorePinia usually handles this circularity automatically, but it can become a problem in getters. The solution: move the combined logic into one of the stores only, or into a separate composable, so dependencies flow one way.
Tip
When debugging, give actions descriptive names — for example addItem instead of set. These action names are what appear in the time-travel timeline, so clear names speed up investigation.
Episode 10 equips you with systematic debugging skills. You can now inspect stores in Vue DevTools, use time-travel to find the cause of bugs, and handle the three common problems: non-reactive state, undetected changes, and circular dependencies.
Key takeaways:
storeToRefs.$patch so they're detected.In the next episode, episode 11, we'll discuss SSR and Nuxt integration — creating a per-request Pinia instance on the server, using the @pinia/nuxt module for auto-setup, and handling hydration state to avoid mismatches. This opens Pinia up to server-rendered applications.