State Is the Missing Layer in Web Components
React stands apart from other major JavaScript frameworks in one notable way: there is no single blessed approach to global state. Developers pick from useState, Context, or any of a sprawling ecosystem of third-party libraries. Other frameworks ship with a canonical solution built in. State, like components, has become a foundational abstraction for building interactive interfaces — tracking whether a sidebar is open, what comments exist, or who is logged in.
What remains surprising is that native web components never attempted to address state at all. That gap has left developers to invent their own patterns for making state work both inside and across custom elements.
A Micro-Framework for Reactive Web Components
Evan You’s @vue/lit demonstrates one direction. The microframework combines lit-html for templating and re-rendering with Vue’s reactivity package for state. The total footprint lands around 6kb — a meaningful reduction compared to pulling in a full framework for the same capabilities.
The No-Library Route
Krasimir Tsonev shows how far the pendulum can swing in “Using JavaScript module system for state management.” A state manager, in this view, needs no library at all: it is simply a module that exports an object with values, mutation functions, and listeners. The overhead drops to nearly nothing — but so does the convenience. You give up efficient re-rendering, templating, and component lifecycle management that more robust tools provide.
A Vanilla Data-Attribute Pattern
Leo Bauza’s description of how Viget writes JavaScript offers another library-free approach. All functionality attaches to the DOM through data-* attributes, each mapped to a dedicated JavaScript module that owns that behavior. Global state barely figures into the picture; individual modules manage their own state manually, as seen in the incrementer module of their demo project.
The range of options suggests a practical rule of thumb. For small projects, a hand-rolled pattern can be perfectly adequate. Medium-sized, low-impact work invites experimentation with newer or even experimental tooling. But for large, high-stakes applications, most developers will find more safety in the maturity of well-established libraries — even when that means accepting heavier dependencies.



