Start with ownership, not patterns
Ask which part of the product owns each piece of truth, how long that truth lives, and which events may change it. The interface should render state and express intent; data access and business rules should stay behind explicit boundaries.
A product becomes fragile when the same state has several informal owners. Loading appears in two places, navigation depends on unrelated flags, and a background refresh changes information the current screen no longer expects.
Dependencies should be replaceable
Use explicit interfaces for remote data, storage, identity, measurement, and time. Replaceable dependencies make important scenarios reproducible: expired sessions, slow networks, empty portfolios, and partial failures.
- Keep interfaces small and based on capabilities.
- Make time and identifiers controllable when deterministic behaviour matters.
- Model real failure states in previews and tests.
- Keep transport details outside the interface layer.
Navigation is product state
Links, restoration, modal flows, and access gates all change what navigation means. Model destinations explicitly and test transitions instead of assembling journeys through scattered side effects.
Measurement closes the loop
Production needs meaningful error categories, performance markers, and privacy-aware outcome measurement. The goal is enough context to answer what failed, at which step, and whether recovery worked.
The calm foundation
A strong product is boring in the best way: ownership is clear, dependencies are replaceable, navigation is explicit, and failures are visible. That calmness makes future product work faster.