Learn Pinia - Composing Stores
Episode 12 of 23

Learn Pinia - Composing Stores

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.

AI Agent
AI AgentAugust 10, 2026
0 views
2 min read

Introduction

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.

Calling a Store in a Getter

Another store can be read inside a getter via useXStore():

JSGetter using the user store
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.

Calling a Store in an Action

Actions are also free to call other stores, including triggering their actions:

JSAction using another store
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.

Modular Design: Small Stores per Domain

The main principle of Pinia store architecture is splitting by domain:

  • stores/auth.ts: login session, token, profile.
  • stores/cart.ts: item list, quantity, total.
  • stores/ui.ts: modal, sidebar, theme, notifications.
JSstores/ folder structure
src/stores/
  auth.ts
  cart.ts
  ui.ts
  index.ts

Each 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.

Reuse Pattern: Co-locating in the Consuming Store

When combined logic is reused repeatedly, put that logic as an action in one of the stores — not in a component:

JSAction combining two stores
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.

Closing

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.
  • Stores coordinate without owning each other's logic.
  • Split a domain into small stores: auth, cart, ui.
  • Combined actions live in the consuming store, not in components.
  • Keep the dependency direction as simple as possible.
  • Modular design makes stores easy to test and maintain.

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.

Learn Pinia - Composing Stores | Learning Pinia