Maintaining state is an easily solved problem severely over engineered by frameworks. The central issue why this becomes so complicated is because developers who aren't comfortable writing original code would rather deal with an ocean of configurations than a few architectural decisions.<p>That is problematic because configurations are settings not decisions, which means you need work arounds for edge cases and work arounds for the work arounds. If instead you treat everything as a requirement instead of anything as an edge case then you are forced to make decisions and write the corresponding code. New requirements may necessitate refactoring of current decisions down the road, but the code stays clean, small, and deliberate.<p>At the most simple you only need three things: a central consolidated point of settings (object), storage (localStorage), and interactions isolated to their respective purpose (handlers).