← ClaudeAtlas

state-topologylisted

Decide where each piece of state lives — server, URL, client, session — and detect the misclassifications that cause most "wrong data on screen" bugs. Load before designing state for a feature, or when auditing an existing state layer.
soumit-kaz/lazysitter · ★ 1 · Code & Development · score 69
Install: claude install-skill soumit-kaz/lazysitter
# State topology Most bad state designs are a **misclassification**, not a bad library choice. Classify first; place second. ## The four kinds | kind | owned by | lives in | the failure when misplaced | |---|---|---|---| | **server state** | the backend | the server-state cache (react-query/SWR/Apollo) | copied into `useState` → goes stale, and nothing tells you | | **URL state** | the URL | search params / route segments | unlinkable, unshareable, back button does the wrong thing | | **client state** | this UI | the nearest common consumer | lifted too high → re-renders everything; too low → drilled | | **session state** | the session | one well-known store | duplicated → theme/locale disagree between screens | ## The single biggest bug source: server state copied into client state ```jsx const { data } = useQuery(['user', id], fetchUser); const [user, setUser] = useState(data); // ← a second copy nothing keeps in sync ``` Once copied, the cache can update and the copy will not. Every "it shows the old value until I refresh" bug traces back here. Legitimate reasons to copy exist — an editable draft of a fetched entity is the main one. When you do, say explicitly **what reconciles them**: when the draft resets, what happens if the server value changes mid-edit, and whether the user is told. ## URL state — decide it early, it is expensive to retrofit Belongs in the URL: filters, search terms, sort, pagination, selected tab, selected entity id, and often whether