3 min read

Vue State Management: When You Don’t Actually Need a Store

Vue State Management: When You Don’t Actually Need a Store

Pinia is excellent.

It’s well-designed, predictable, devtools-friendly, and officially recommended by the Vue team. If you’re building anything beyond a toy app, chances are you’re using it—or planning to.

But somewhere along the way, a quiet shift happened:

State management became the default solution instead of the intentional one.

I see it constantly in production Vue apps—stores created not because the app needs shared state, but because “that’s how we do things now.”

Let’s talk about when you don’t actually need a store—and what usually works better instead.


The Rise of “Store-First” Thinking

Pinia lowered the barrier to global state so effectively that many teams stopped asking why a piece of state should be global at all.

The result:

  • One store per feature
  • One store per page
  • One store per component
  • Stores holding form inputs, toggles, loading flags, and temporary UI state

None of this is malicious. It’s usually well-intentioned structure.

But structure without intent becomes noise.


What State Management Is Actually For

True state management exists to solve shared, long-lived, cross-cutting concerns.

Good candidates for a store:

  • Auth and user context
  • Feature flags
  • Subscription / access state
  • Global preferences (theme, locale)
  • Cached API data shared across routes
  • Data that must survive navigation

These are application-level concerns.

What state management is not for:

  • Form input values
  • Local UI toggles
  • Temporary request state
  • Derived values
  • Data owned by a single component tree

If the state doesn’t meaningfully outlive the component that owns it, a store is usually the wrong tool.


The Most Common Pinia Misuses I See

Here’s where things get uncomfortable—in a useful way.

Stores as glorified props

If a store has exactly one consumer, it’s not shared state. It’s a global variable with extra steps.

One-component stores

If deleting the component would also delete the store with no impact elsewhere, the store doesn’t belong.

UI state promoted to global state

Modal visibility, accordion state, loading flags—these are local concerns.

Stores replacing basic reactivity

I’ve seen stores used where a simple ref would have been clearer, cheaper, and easier to reason about.

A good rule of thumb:

If the store exists mostly to avoid passing props, it’s probably hiding a design problem—not solving one.


What You Should Use Instead (Most of the Time)

Vue already gives you excellent tools before you ever reach for a store.

Local reactivity

ref and reactive are cheap, explicit, and perfectly scoped.

Props and emits

Yes, even if it feels “old-fashioned.” Data ownership stays clear. Debugging stays sane.

Composables

Reusable logic without forcing shared state. This is where most “store-ish” code actually belongs.

Computed values

If it can be derived, derive it. Don’t store it.

These tools keep state close to where it’s used, which is usually where it belongs.


A Simple Decision Test

Before creating a store, ask yourself:

  • Is this state shared across distant parts of the app?
  • Does it need to survive route changes?
  • Does it represent application state rather than UI state?
  • Would this still make sense without Vue DevTools?

If most answers are “no,” skip the store.

This test alone would eliminate half the unnecessary Pinia usage I see.


When Pinia Is the Right Choice

This isn’t an anti-Pinia article.

Pinia shines when:

  • State truly is global
  • Multiple unrelated components depend on it
  • You need predictable mutation flows
  • Debugging history matters
  • The state models the application, not the UI

Used intentionally, Pinia makes apps easier to reason about—not harder.


The Hidden Cost of Too Many Stores

Overusing stores introduces quiet debt:

  • Mental overhead when navigating the codebase
  • Harder refactors due to implicit coupling
  • Debugging flows that jump across files unnecessarily
  • A “global by default” mindset that erodes boundaries

None of this breaks immediately. It just makes everything slightly heavier than it needs to be.

Those are the hardest problems to fix later.


Simpler State, Clearer Apps

Good state management isn’t about using the right tool everywhere.

It’s about knowing when not to use it.

If your Vue app feels easier to reason about without a store, that’s not a failure of architecture—it’s a sign you’re paying attention.

And paying attention scales better than any library ever will.