Stores can use each other. This episode covers how to call another store inside getters and actions, splitting a domain into small stores like auth, cart, and ui, and reuse patterns with a real example of a cart store that depends on a user store.

One of Pinia's advantages is stores that are modular and can use each other. Instead of one giant store holding every domain, you split it into small stores per feature, then connect them when needed. This pattern is called composing stores.
Episode 12 covers how to call another store inside getters and actions, split a domain into small stores, and apply reuse patterns with a real example: a cart store that depends on a user store.
Another store can be read inside a getter via useXStore():
import { useUserStore } from '@/stores/user'
export const useCartStore = defineStore('cart', {
state: () => ({
items: [] as { name: string; price: number; qty: number }[],
}),
getters: {
isMemberPrice: () => {
const userStore = useUserStore()
return userStore.isMember
},
},
})useUserStore() inside the getter gives access to another store's state. Because the getter executes while the store is active, this call is safe and stays reactive to changes in the user store.
Actions are also free to call other stores, including triggering their actions:
import { useUserStore } from '@/stores/user'
export const useCartStore = defineStore('cart', {
state: () => ({ items: [] as { name: string; price: number }[] }),
actions: {
checkout() {
const userStore = useUserStore()
if (!userStore.isLoggedIn) {
userStore.promptLogin()
return false
}
return true
},
},
})userStore.promptLogin() runs an action from another store. Coordination like this keeps a single responsibility per store: cart manages items, user manages the login session.
The main principle of Pinia store architecture is splitting by domain:
src/stores/
auth.ts
cart.ts
ui.ts
index.tsEach store is small, easy to test, and self-contained. cart may depend on auth for member discounts, ui may read auth to display a different menu, but no store piles up the entire app's logic.
When combined logic is reused repeatedly, put that logic as an action in one of the stores — not in a component:
actions: {
addToCartAndNotify(item) {
this.addItem(item)
const uiStore = useUiStore()
uiStore.showToast(`${item.name} added`)
},
}addToCartAndNotify(item) combines the cart mutation with a UI notification in a single action. Components just call one method, and responsibilities stay spread across the right stores.
Tip
Keep the dependency direction as simple as possible. If it becomes hard to track who uses whom, consider moving the combined logic into a composable — rather than adding a new dependency.
Episode 12 shows off Pinia's power as a modular system. You can now call other stores in getters and actions, split an app into small per-domain stores, and apply reuse patterns with inter-store coordination.
Key takeaways:
useXStore() is called inside another store's getters and actions.In the next episode, episode 13, we'll discuss performance and reactivity tuning — controlling re-renders with storeToRefs and granular access, using $subscribe with the detached option, and batching updates with $patch for a more responsive app.