Feature architecture and state ownership
Organize by business capability, not by file type.
Vertical feature shape
orders/
data-access/
domain/
feature-list/
feature-detail/
ui/
orders.routes.ts
Keep dependencies flowing toward stable domain/application contracts. Shared must not become a dumping ground.
State categories
- server state: remote truth, caching, freshness, invalidation;
- URL state: navigation and shareable filters;
- feature state: workflow state scoped to one capability;
- component state: local interaction;
- persisted preference: deliberately versioned browser state.
Put each state in the narrowest owner that serves all real consumers.
Stores
A small signal service can be a good feature store. Larger event/state libraries help when auditability, devtools, entity patterns, or cross-feature workflows justify them. Do not adopt global state before defining ownership.
Ports and adapters
Application workflows depend on interfaces or stable services; HTTP, storage, analytics, and browser APIs are adapters. This makes testing and SSR boundaries clear.
Libraries and monorepos
Libraries need consumers, API contracts, ownership, and independent value. Enforce boundaries with lint/build tooling. Too many tiny libraries create versioning and navigation cost.
Feynman check
Draw one piece of state and its owner. List every reader and writer. If many unrelated features write it, the product model may be unclear.