Modern State Management: Beyond Redux—A Deep Dive into Architecture

9/12/2025

The real question is architecture, not library

I used Redux for years. It worked, but on some teams it came with too much ceremony for simple state updates.

Now I pick state tools based on architecture needs, not trend cycles. The hard part is not picking a library. The hard part is deciding what state belongs where.

What changed in practice

The biggest shift for me was moving from one giant store mindset to smaller, domain-shaped state.

  • Components subscribe to less data
  • Re-renders are easier to reason about
  • Teams can refactor one slice without touching everything

That change alone improved performance debugging and onboarding speed on larger apps.

A practical state split I use

I separate state into three buckets before writing code:

  1. Local UI state (modal open, input draft, tab index)
  2. Client app state (cross-screen preferences, wizard progress)
  3. Server state (API data, cache, loading/error lifecycle)

Rule: I do not force server state into client global stores if a query library can own it better.

Performance habits that actually moved numbers

  • Keep selectors/derived state small and explicit
  • Avoid broad subscriptions to large objects
  • Co-locate state with the feature unless reuse is proven
  • Profile real screens before introducing complex optimization

In one dashboard project, just narrowing subscriptions removed a lot of noisy re-renders without any framework change.

How I structure code so it stays maintainable

I organize state by domain, not by state-tool primitives.

  • `features/cart/state` owns cart state and hooks
  • `features/auth/state` owns auth state and hooks
  • UI code imports domain hooks, not internal atoms/store internals

This gives each feature a clean boundary and makes refactors less scary.

When teams get state wrong

  • Everything becomes global too early
  • Server and client state are mixed without clear ownership
  • Optimization is added before measurement
  • Feature teams bypass boundaries and read internals directly

I’ve made all four mistakes. Each one slows delivery later.

What I’d do differently if restarting

  • Start with a clear state taxonomy on day one
  • Use query libraries for server state from the start
  • Document domain boundaries early
  • Treat global state as expensive, not default

Closing checklist

  • Can I explain why each state slice is local vs global?
  • Is server state owned by the right tool?
  • Do components subscribe only to what they need?
  • Can a new engineer find state ownership quickly?

If yes, your state layer will scale better than the average "just pick a library" setup.

Read More