I believed “stateless = simple”
Like many frontend engineers, I bought into the idea early.
No shared mutable state.
No surprises.
Just clean functions and predictable flows.
So I decided to go all in and build a frontend that was as stateless as possible.
It looked clean — until it wasn’t
At first, everything felt disciplined.
Then the app grew.
And “stateless” slowly turned into:
State duplicated across hooks
State mirrored in the URL
State cached, then reconstructed
State synchronized across tabs
State re‑derived after refreshes
State invalidated in multiple places
Nothing was explicitly wrong.
But nothing felt simple anymore.
Debugging became the real problem
Fixing a single UI bug meant answering questions like:
Is this value stale or recomputed?
Did an effect run twice?
Is this coming from cache or network?
Why does refreshing “fix” it?
Where is the source of truth?
The complexity wasn’t visible anymore — it was emergent.
The realization that changed everything
Stateless…