The state object is just a regular JavaScript object. I prefer to avoid classes as they increase complexity for almost no substantive benefit.
Changes to the UI are handled as events whether those events are from user interactions, HTTP responses, or web socket data events.
I update the DOM using old school DOM methods and some custom DOM methods I have written to do things the standards do not provide.
This stuff that people cry tears of blood over is easy and very basic. I really think the bane of evil is addEventListener allowing multiple handlers for the same events which allows laziness and super increased complexity.
What’s more challenging is writing test automation that executes in the browser and coordinates between browsers of different computers.
It is a complete GUI with full state management and the browser part of the application is very tiny.
Do you use anything to render your view or do you construct the nodes and insert them into the DOM directly?
Is your centrally available object an instance of a class or is it a plain JavaScript object?
Does it manage the state for all your UI or is it segmented in some way?
How do you drive changes to your UI? Is there an imperative process that renders the UI when you know the data model has changed or is your state object an observable or something that your views subscribe to?