<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: iDev-Games</title>
    <description>The latest articles on DEV Community by iDev-Games (@idevgames).</description>
    <link>https://dev.to/idevgames</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1050213%2Fe693562c-e79e-4cc1-8346-d542ee592839.png</url>
      <title>DEV Community: iDev-Games</title>
      <link>https://dev.to/idevgames</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/idevgames"/>
    <language>en</language>
    <item>
      <title>A New Stack for Turning HTML &amp; CSS Into an Application Layer</title>
      <dc:creator>iDev-Games</dc:creator>
      <pubDate>Tue, 02 Jun 2026 13:44:54 +0000</pubDate>
      <link>https://dev.to/idevgames/a-new-stack-for-turning-html-css-into-an-application-layer-27b0</link>
      <guid>https://dev.to/idevgames/a-new-stack-for-turning-html-css-into-an-application-layer-27b0</guid>
      <description>&lt;p&gt;&lt;em&gt;(&lt;a href="https://github.com/iDev-Games/State-JS" rel="noopener noreferrer"&gt;State.js&lt;/a&gt;, &lt;a href="https://github.com/iDev-Games/Motion-JS" rel="noopener noreferrer"&gt;Motion.js&lt;/a&gt;, &lt;a href="https://github.com/iDev-Games/Gravity-JS" rel="noopener noreferrer"&gt;Gravity.js&lt;/a&gt;, &lt;a href="https://github.com/iDev-Games/Cursor-JS" rel="noopener noreferrer"&gt;Cursor.js&lt;/a&gt;, &lt;a href="https://github.com/iDev-Games/Keys-JS" rel="noopener noreferrer"&gt;Keys.js&lt;/a&gt; — a browser‑native ecosystem)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For years, frontend development has revolved around one assumption:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;If you want interactivity, state, animation, or physics — you need a framework.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;React, Vue, Svelte, Solid… all incredible tools, but they all share the same core idea:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JS owns the state
&lt;/li&gt;
&lt;li&gt;JS owns the rendering
&lt;/li&gt;
&lt;li&gt;JS owns the reactivity
&lt;/li&gt;
&lt;li&gt;JS owns the lifecycle
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HTML and CSS are treated as passive output layers.&lt;/p&gt;

&lt;p&gt;But what if that assumption is wrong?&lt;/p&gt;

&lt;p&gt;What if the browser already &lt;em&gt;has&lt;/em&gt; the primitives we need — and we just haven’t been using them as a unified system?&lt;/p&gt;

&lt;p&gt;That’s the question that led me to build a small ecosystem of libraries that all share one philosophy:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Expose browser signals to CSS.&lt;br&gt;&lt;br&gt;
Let HTML declare behaviour.&lt;br&gt;&lt;br&gt;
Let CSS render it.&lt;br&gt;&lt;br&gt;
Use JS only as the glue.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This post introduces that ecosystem.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Why This Stack Exists&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Modern frontend development is powerful — but also heavy.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bundlers
&lt;/li&gt;
&lt;li&gt;Virtual DOMs
&lt;/li&gt;
&lt;li&gt;Component compilers
&lt;/li&gt;
&lt;li&gt;State libraries
&lt;/li&gt;
&lt;li&gt;Effect systems
&lt;/li&gt;
&lt;li&gt;Re-renders
&lt;/li&gt;
&lt;li&gt;Signals
&lt;/li&gt;
&lt;li&gt;Hooks
&lt;/li&gt;
&lt;li&gt;Stores
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All to build things the browser can already do.&lt;/p&gt;

&lt;p&gt;Meanwhile, CSS has quietly evolved into a &lt;em&gt;reactive rendering engine&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSS variables
&lt;/li&gt;
&lt;li&gt;calc()
&lt;/li&gt;
&lt;li&gt;transitions
&lt;/li&gt;
&lt;li&gt;animations
&lt;/li&gt;
&lt;li&gt;container queries
&lt;/li&gt;
&lt;li&gt;view transitions
&lt;/li&gt;
&lt;li&gt;scroll-driven animations
&lt;/li&gt;
&lt;li&gt;:has()
&lt;/li&gt;
&lt;li&gt;@property
&lt;/li&gt;
&lt;li&gt;custom easing
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And HTML has evolved into a &lt;em&gt;declarative configuration surface&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;attributes
&lt;/li&gt;
&lt;li&gt;custom elements
&lt;/li&gt;
&lt;li&gt;dataset
&lt;/li&gt;
&lt;li&gt;templates
&lt;/li&gt;
&lt;li&gt;inert
&lt;/li&gt;
&lt;li&gt;popovers
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the question became:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What if we treat HTML + CSS as the application layer,&lt;br&gt;&lt;br&gt;
and JavaScript as the runtime that feeds them state?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s the foundation of this stack.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;The Stack (Browser‑Native, Declarative, Modular)&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Each library does one thing, exposes one set of signals, and stays tiny.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;1. State.js&lt;/strong&gt; — &lt;em&gt;CSS‑Reactive State Engine&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;State.js exposes reactive state directly to CSS variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"player"&lt;/span&gt;
     &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-state-watch=&lt;/span&gt;&lt;span class="s"&gt;"health,score"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-var=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
     &lt;span class="na"&gt;data-health=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt;
     &lt;span class="na"&gt;data-health-min=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
     &lt;span class="na"&gt;data-health-max=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt;
     &lt;span class="na"&gt;data-score=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"health-bar"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No re-renders.&lt;br&gt;&lt;br&gt;
No virtual DOM.&lt;br&gt;&lt;br&gt;
No diffing.&lt;br&gt;&lt;br&gt;
Just state → CSS → rendering.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;2. Motion.js&lt;/strong&gt; — &lt;em&gt;Scroll, Time &amp;amp; Viewport Signals&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Motion.js exposes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scroll progress
&lt;/li&gt;
&lt;li&gt;element visibility
&lt;/li&gt;
&lt;li&gt;time
&lt;/li&gt;
&lt;li&gt;easing
&lt;/li&gt;
&lt;li&gt;playback
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…as CSS variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-motion&lt;/span&gt; &lt;span class="na"&gt;data-motion-var=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; &lt;span class="na"&gt;data-motion-duration=&lt;/span&gt;&lt;span class="s"&gt;"2000"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- CSS animates based on scroll/time --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;3. Gravity.js&lt;/strong&gt; — &lt;em&gt;Physics Exposed to CSS&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Gravity.js simulates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;gravity
&lt;/li&gt;
&lt;li&gt;velocity
&lt;/li&gt;
&lt;li&gt;friction
&lt;/li&gt;
&lt;li&gt;forces
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…and exposes them as CSS variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-gravity&lt;/span&gt; &lt;span class="na"&gt;data-gravity-type=&lt;/span&gt;&lt;span class="s"&gt;"static"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- CSS animates based on physics --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lets designers build physical-feeling interfaces without writing physics code.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;4. Cursor.js&lt;/strong&gt; — &lt;em&gt;Cursor State as CSS Variables&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Cursor.js exposes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;x/y position
&lt;/li&gt;
&lt;li&gt;velocity
&lt;/li&gt;
&lt;li&gt;direction
&lt;/li&gt;
&lt;li&gt;hover state
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…to CSS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-cursor&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- CSS reacts to cursor movement --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;5. Keys.js&lt;/strong&gt; — &lt;em&gt;Keyboard State as CSS Variables&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Keys.js exposes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;key pressed
&lt;/li&gt;
&lt;li&gt;key held
&lt;/li&gt;
&lt;li&gt;key released
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…to CSS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-keys&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- CSS reacts to keyboard input --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  &lt;strong&gt;Why This Works&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Because CSS is already a reactive rendering engine.&lt;/p&gt;

&lt;p&gt;When you expose state to CSS variables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSS handles the rendering
&lt;/li&gt;
&lt;li&gt;CSS handles the animation
&lt;/li&gt;
&lt;li&gt;CSS handles the interpolation
&lt;/li&gt;
&lt;li&gt;CSS handles the transitions
&lt;/li&gt;
&lt;li&gt;CSS handles the layout
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;JavaScript becomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the state updater
&lt;/li&gt;
&lt;li&gt;the signal provider
&lt;/li&gt;
&lt;li&gt;the glue
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not the renderer.&lt;/p&gt;

&lt;p&gt;This flips the traditional model:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Traditional&lt;/th&gt;
&lt;th&gt;This Stack&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;JS renders&lt;/td&gt;
&lt;td&gt;CSS renders&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JS animates&lt;/td&gt;
&lt;td&gt;CSS animates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JS manages state&lt;/td&gt;
&lt;td&gt;JS exposes state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML is passive&lt;/td&gt;
&lt;td&gt;HTML is declarative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSS is styling&lt;/td&gt;
&lt;td&gt;CSS is reactive&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Why Not Just Use React?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;React is incredible — but it’s a &lt;strong&gt;UI framework&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This stack is a &lt;strong&gt;browser-native runtime&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;React owns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rendering
&lt;/li&gt;
&lt;li&gt;state
&lt;/li&gt;
&lt;li&gt;components
&lt;/li&gt;
&lt;li&gt;lifecycle
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This stack owns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;signals
&lt;/li&gt;
&lt;li&gt;state exposure
&lt;/li&gt;
&lt;li&gt;declarative behaviour
&lt;/li&gt;
&lt;li&gt;CSS-driven rendering
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They’re not competitors.&lt;br&gt;&lt;br&gt;
They’re different layers.&lt;/p&gt;

&lt;p&gt;You could even use them &lt;em&gt;together&lt;/em&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;What This Enables&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;This stack makes it trivial to build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;physical-feeling UI
&lt;/li&gt;
&lt;li&gt;scroll-reactive UI
&lt;/li&gt;
&lt;li&gt;cursor-reactive UI
&lt;/li&gt;
&lt;li&gt;keyboard-reactive UI
&lt;/li&gt;
&lt;li&gt;time-based UI
&lt;/li&gt;
&lt;li&gt;stateful UI
&lt;/li&gt;
&lt;li&gt;animated UI
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…without writing application logic.&lt;/p&gt;

&lt;p&gt;It also opens the door to something bigger:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A new authoring medium where designers can build interactive systems without touching JS.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Think:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Figma-like tools that export real interactions
&lt;/li&gt;
&lt;li&gt;CSS-driven physics
&lt;/li&gt;
&lt;li&gt;declarative behaviour graphs
&lt;/li&gt;
&lt;li&gt;HTML as the app layer
&lt;/li&gt;
&lt;li&gt;CSS as the rendering engine
&lt;/li&gt;
&lt;li&gt;JS as the runtime
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the direction the web has been moving toward for years.&lt;/p&gt;

&lt;p&gt;This stack just pushes it further.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Where This Goes Next&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;This isn’t a framework.&lt;br&gt;&lt;br&gt;
It’s not a React competitor.&lt;br&gt;&lt;br&gt;
It’s not a “React killer.”&lt;/p&gt;

&lt;p&gt;It’s a &lt;strong&gt;new layer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A browser-native layer.&lt;/p&gt;

&lt;p&gt;A declarative layer.&lt;/p&gt;

&lt;p&gt;A layer that asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How much interactivity can we get from HTML + CSS before we need application code?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the answer so far is:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;More than people think.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;If You Want to Explore the Stack&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Here are the individual libraries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/iDev-Games/State-JS" rel="noopener noreferrer"&gt;&lt;strong&gt;State.js&lt;/strong&gt;&lt;/a&gt; — CSS-reactive state
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/iDev-Games/Motion-JS" rel="noopener noreferrer"&gt;&lt;strong&gt;Motion.js&lt;/strong&gt;&lt;/a&gt; — scroll/time signals
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/iDev-Games/Gravity-JS" rel="noopener noreferrer"&gt;&lt;strong&gt;Gravity.js&lt;/strong&gt;&lt;/a&gt; — physics signals
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/iDev-Games/Cursor-JS" rel="noopener noreferrer"&gt;&lt;strong&gt;Cursor.js&lt;/strong&gt;&lt;/a&gt; — cursor signals
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/iDev-Games/Keys-JS" rel="noopener noreferrer"&gt;&lt;strong&gt;Keys.js&lt;/strong&gt;&lt;/a&gt; — keyboard signals
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each one is tiny, focused, and works independently.&lt;/p&gt;

&lt;p&gt;But together, they form something new.&lt;/p&gt;

&lt;p&gt;A stack.&lt;br&gt;&lt;br&gt;
A philosophy.&lt;br&gt;&lt;br&gt;
A new way of thinking about the browser.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>opensource</category>
      <category>beginners</category>
      <category>architecture</category>
    </item>
    <item>
      <title>The Scale Misconception: Why State.js Scales Endlessly (Where Traditional SPAs Fail)</title>
      <dc:creator>iDev-Games</dc:creator>
      <pubDate>Mon, 01 Jun 2026 14:22:07 +0000</pubDate>
      <link>https://dev.to/idevgames/the-scale-misconception-why-statejs-scales-endlessly-where-traditional-spas-fail-2k8k</link>
      <guid>https://dev.to/idevgames/the-scale-misconception-why-statejs-scales-endlessly-where-traditional-spas-fail-2k8k</guid>
      <description>&lt;p&gt;For years, frontend developers have been told the same thing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you want to build a large-scale application, you need a large-scale JavaScript framework.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The assumption is everywhere. If your application is expected to grow, you're expected to adopt a complex client-side architecture built around React, Vue, Angular, or another framework that manages application state entirely within the browser.&lt;/p&gt;

&lt;p&gt;The industry has largely accepted this as fact.&lt;/p&gt;

&lt;p&gt;But what if we've misunderstood what "scaling" actually means?&lt;/p&gt;

&lt;p&gt;Because in practice, many large Single Page Applications (SPAs) don't scale by becoming simpler, faster, or easier to maintain. They scale by accumulating more client-side state, larger JavaScript bundles, more hydration overhead, and increasingly complex frontend architectures.&lt;/p&gt;

&lt;p&gt;State.js takes a fundamentally different approach.&lt;/p&gt;

&lt;p&gt;Instead of treating the browser as an application server, State.js acts as a lightweight visual orchestration layer for the DOM. Business logic remains on the backend where it belongs, while State.js handles reactive visual state directly within HTML and CSS.&lt;/p&gt;

&lt;p&gt;The result is an architecture that can scale from a simple landing page to a massive enterprise platform without requiring an ever-growing client-side application layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Modern Misunderstanding of Frontend Scalability
&lt;/h2&gt;

&lt;p&gt;When developers talk about scalability, they're often referring to frontend frameworks and state management solutions.&lt;/p&gt;

&lt;p&gt;Questions usually sound like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can React handle a million users?&lt;/li&gt;
&lt;li&gt;Will Vue scale with a growing codebase?&lt;/li&gt;
&lt;li&gt;Should enterprise applications use Angular?&lt;/li&gt;
&lt;li&gt;Which frontend framework scales best?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The problem is that these questions focus on tooling instead of architecture.&lt;/p&gt;

&lt;p&gt;A frontend framework doesn't determine whether an application scales.&lt;/p&gt;

&lt;p&gt;Architectural boundaries do.&lt;/p&gt;

&lt;p&gt;Most applications struggle to scale because responsibilities become blurred. Business logic, security concerns, application data, visual state, and rendering behavior become tightly coupled inside the browser.&lt;/p&gt;

&lt;p&gt;As complexity increases, the frontend grows into a second application that mirrors the backend.&lt;/p&gt;

&lt;p&gt;That's where scalability problems begin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proper Separation of Concerns: Security and Logic
&lt;/h2&gt;

&lt;p&gt;To understand why State.js scales differently, it's important to separate two completely different categories of data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Business-Critical Data
&lt;/h3&gt;

&lt;p&gt;This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User authentication&lt;/li&gt;
&lt;li&gt;Financial transactions&lt;/li&gt;
&lt;li&gt;Permission validation&lt;/li&gt;
&lt;li&gt;Database operations&lt;/li&gt;
&lt;li&gt;API integrations&lt;/li&gt;
&lt;li&gt;Business rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This data is sensitive, authoritative, and security-critical.&lt;/p&gt;

&lt;p&gt;It belongs on the server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Visual State
&lt;/h3&gt;

&lt;p&gt;This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whether a menu is open&lt;/li&gt;
&lt;li&gt;Which tab is active&lt;/li&gt;
&lt;li&gt;Animation progress&lt;/li&gt;
&lt;li&gt;Component visibility&lt;/li&gt;
&lt;li&gt;Theme preferences&lt;/li&gt;
&lt;li&gt;Interactive UI behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This state exists purely to control presentation.&lt;/p&gt;

&lt;p&gt;It belongs in the frontend.&lt;/p&gt;

&lt;p&gt;The distinction seems obvious, yet modern SPA architectures frequently blur these responsibilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  The SPA Mistake
&lt;/h2&gt;

&lt;p&gt;Traditional Single Page Applications often require developers to rebuild large portions of their backend architecture in JavaScript.&lt;/p&gt;

&lt;p&gt;The process usually looks something like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fetch raw JSON from APIs&lt;/li&gt;
&lt;li&gt;Store it in a frontend state manager&lt;/li&gt;
&lt;li&gt;Validate and transform the data&lt;/li&gt;
&lt;li&gt;Synchronize state across components&lt;/li&gt;
&lt;li&gt;Reconstruct UI from that state&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The frontend effectively becomes a second application layer.&lt;/p&gt;

&lt;p&gt;As systems grow, developers end up managing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large client-side state trees&lt;/li&gt;
&lt;li&gt;Complex dependency chains&lt;/li&gt;
&lt;li&gt;Hydration issues&lt;/li&gt;
&lt;li&gt;State synchronization problems&lt;/li&gt;
&lt;li&gt;Security considerations&lt;/li&gt;
&lt;li&gt;Performance bottlenecks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The browser becomes responsible for work that the server is already capable of handling.&lt;/p&gt;

&lt;p&gt;This duplication introduces complexity that often gets mistaken for scalability.&lt;/p&gt;

&lt;h2&gt;
  
  
  The State.js Approach
&lt;/h2&gt;

&lt;p&gt;State.js follows a much simpler principle:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The backend remains the source of truth.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Whether you're using Laravel, WordPress, Ruby on Rails, Node.js, Django, or another backend framework, your server handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Validation&lt;/li&gt;
&lt;li&gt;Authorization&lt;/li&gt;
&lt;li&gt;Business rules&lt;/li&gt;
&lt;li&gt;Database interactions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The server renders the HTML.&lt;/p&gt;

&lt;p&gt;State.js then operates directly at the DOM layer, managing visual behavior without attempting to duplicate backend responsibilities.&lt;/p&gt;

&lt;p&gt;Instead of building and maintaining massive JavaScript object trees, State.js connects state directly to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML attributes&lt;/li&gt;
&lt;li&gt;CSS custom properties&lt;/li&gt;
&lt;li&gt;DOM elements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This creates a clear separation between application logic and presentation logic.&lt;/p&gt;

&lt;p&gt;Security stays on the server.&lt;/p&gt;

&lt;p&gt;Interactivity stays in the browser.&lt;/p&gt;

&lt;p&gt;Each layer performs the task it was designed to handle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Architecture Scales Better
&lt;/h2&gt;

&lt;p&gt;The biggest scalability gains don't come from adding more frontend infrastructure.&lt;/p&gt;

&lt;p&gt;They come from reducing unnecessary complexity.&lt;/p&gt;

&lt;p&gt;State.js achieves this through architectural simplicity.&lt;/p&gt;

&lt;h3&gt;
  
  
  No Business Logic Duplication
&lt;/h3&gt;

&lt;p&gt;The backend remains responsible for data and business rules.&lt;/p&gt;

&lt;p&gt;You don't need to recreate validation systems, permission layers, or database structures inside the browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  Smaller JavaScript Footprint
&lt;/h3&gt;

&lt;p&gt;Because State.js focuses exclusively on visual state, applications avoid shipping unnecessary client-side infrastructure.&lt;/p&gt;

&lt;p&gt;Smaller bundles mean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster page loads&lt;/li&gt;
&lt;li&gt;Better mobile performance&lt;/li&gt;
&lt;li&gt;Lower memory consumption&lt;/li&gt;
&lt;li&gt;Improved user experience&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Reduced Cognitive Overhead
&lt;/h3&gt;

&lt;p&gt;Developers can reason about systems more easily when responsibilities are clearly separated.&lt;/p&gt;

&lt;p&gt;The backend handles business logic.&lt;/p&gt;

&lt;p&gt;State.js handles presentation state.&lt;/p&gt;

&lt;p&gt;There is no ambiguity about where functionality belongs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scaling Everywhere HTML Exists
&lt;/h2&gt;

&lt;p&gt;One of the most overlooked benefits of State.js is its portability.&lt;/p&gt;

&lt;p&gt;Because it operates directly on native HTML and the DOM, it works virtually anywhere HTML is generated.&lt;/p&gt;

&lt;p&gt;That includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Laravel applications&lt;/li&gt;
&lt;li&gt;WordPress websites&lt;/li&gt;
&lt;li&gt;Ruby on Rails platforms&lt;/li&gt;
&lt;li&gt;Node.js servers&lt;/li&gt;
&lt;li&gt;PHP applications&lt;/li&gt;
&lt;li&gt;Enterprise CMS systems&lt;/li&gt;
&lt;li&gt;Static site generators&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don't need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complex build pipelines&lt;/li&gt;
&lt;li&gt;Framework migrations&lt;/li&gt;
&lt;li&gt;Hydration layers&lt;/li&gt;
&lt;li&gt;Frontend rewrites&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You simply integrate State.js into existing HTML output.&lt;/p&gt;

&lt;p&gt;This makes it particularly attractive for organizations with large legacy systems that need modern interactivity without rebuilding their entire frontend stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Scalable E-Commerce Example
&lt;/h2&gt;

&lt;p&gt;Consider a shopping cart.&lt;/p&gt;

&lt;p&gt;Many SPA architectures maintain the entire cart structure in browser memory, synchronizing changes between components and APIs.&lt;/p&gt;

&lt;p&gt;With State.js, the server remains responsible for cart management.&lt;/p&gt;

&lt;p&gt;The frontend simply reflects the current state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"cart-manager"&lt;/span&gt;
     &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-state-items=&lt;/span&gt;&lt;span class="s"&gt;"3"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-total=&lt;/span&gt;&lt;span class="s"&gt;"149.99"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-view=&lt;/span&gt;&lt;span class="s"&gt;"summary"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"cart-badge"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        var(--state-items)
    &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"cart-overlay"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a user adds an item:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A background request updates the server&lt;/li&gt;
&lt;li&gt;The server calculates the new state&lt;/li&gt;
&lt;li&gt;Updated attributes are returned&lt;/li&gt;
&lt;li&gt;State.js updates the DOM&lt;/li&gt;
&lt;li&gt;CSS handles the visual transition&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The browser focuses on rendering.&lt;/p&gt;

&lt;p&gt;The server focuses on business logic.&lt;/p&gt;

&lt;p&gt;Each system performs the work it does best.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why State.js Scales Endlessly
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Zero Long-Term State Accumulation
&lt;/h3&gt;

&lt;p&gt;Many frontend architectures maintain increasingly large state trees as applications grow.&lt;/p&gt;

&lt;p&gt;State.js binds directly to DOM elements instead.&lt;/p&gt;

&lt;p&gt;When elements are removed, browsers naturally garbage-collect associated state.&lt;/p&gt;

&lt;p&gt;This minimizes long-term memory growth.&lt;/p&gt;

&lt;h3&gt;
  
  
  No Hydration Overhead
&lt;/h3&gt;

&lt;p&gt;Hydration is one of the largest performance costs in modern frontend applications.&lt;/p&gt;

&lt;p&gt;The browser must:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download JavaScript&lt;/li&gt;
&lt;li&gt;Parse JavaScript&lt;/li&gt;
&lt;li&gt;Execute JavaScript&lt;/li&gt;
&lt;li&gt;Reconstruct application state&lt;/li&gt;
&lt;li&gt;Attach event handlers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;State.js avoids this process by operating directly on rendered HTML.&lt;/p&gt;

&lt;p&gt;Interactive behavior becomes available immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  Works with Monoliths and Micro-Frontends
&lt;/h3&gt;

&lt;p&gt;Whether your architecture consists of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One large backend&lt;/li&gt;
&lt;li&gt;Multiple services&lt;/li&gt;
&lt;li&gt;Distributed micro-frontends&lt;/li&gt;
&lt;li&gt;Hybrid systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;State.js remains consistent.&lt;/p&gt;

&lt;p&gt;Any HTML-producing service can emit compatible state attributes without interfering with others.&lt;/p&gt;

&lt;p&gt;This flexibility allows organizations to evolve their architecture without rewriting frontend state management systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Benefits of Server-First Architecture
&lt;/h2&gt;

&lt;p&gt;Security is rarely discussed in frontend scalability conversations.&lt;/p&gt;

&lt;p&gt;It should be.&lt;/p&gt;

&lt;p&gt;Every piece of business logic moved into the browser becomes more exposed and more difficult to control.&lt;/p&gt;

&lt;p&gt;By keeping critical operations on the server:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication remains protected&lt;/li&gt;
&lt;li&gt;Authorization remains centralized&lt;/li&gt;
&lt;li&gt;Validation remains consistent&lt;/li&gt;
&lt;li&gt;Sensitive logic remains private&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;State.js doesn't attempt to solve security in the frontend.&lt;/p&gt;

&lt;p&gt;Instead, it avoids creating the problem in the first place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop Over-Engineering Frontend Scale
&lt;/h2&gt;

&lt;p&gt;Many organizations assume frontend scalability requires more abstraction layers, more state managers, and larger frameworks.&lt;/p&gt;

&lt;p&gt;Often the opposite is true.&lt;/p&gt;

&lt;p&gt;Applications become difficult to scale because too much responsibility has been pushed into the browser.&lt;/p&gt;

&lt;p&gt;State.js takes a different path.&lt;/p&gt;

&lt;p&gt;By keeping business logic on the backend and limiting frontend responsibilities to visual state orchestration, it eliminates much of the complexity that causes large applications to become difficult to maintain.&lt;/p&gt;

&lt;p&gt;The result is a simpler architecture, a smaller JavaScript footprint, better performance, stronger security boundaries, and a frontend that can grow without accumulating unnecessary complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The biggest misconception in modern web development is that large applications require massive client-side frameworks to scale.&lt;/p&gt;

&lt;p&gt;In reality, many SPA architectures introduce complexity by duplicating backend responsibilities in the browser.&lt;/p&gt;

&lt;p&gt;State.js rejects that model.&lt;/p&gt;

&lt;p&gt;Instead of acting as a client-side application platform, it serves as a lightweight visual orchestration layer that works directly with the DOM, CSS custom properties, and native HTML.&lt;/p&gt;

&lt;p&gt;Business logic remains secure on the server.&lt;/p&gt;

&lt;p&gt;Visual state remains fast in the browser.&lt;/p&gt;

&lt;p&gt;And because those responsibilities remain clearly separated, State.js can scale from a simple marketing site to a large enterprise application without requiring the architectural overhead that often makes traditional SPAs difficult to maintain.&lt;/p&gt;

&lt;p&gt;Sometimes the path to better scalability isn't adding more JavaScript.&lt;/p&gt;

&lt;p&gt;It's using less of it.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>beginners</category>
      <category>opensource</category>
    </item>
    <item>
      <title>⭐ State.js + Keys.js Tutorial - Build Interactive UI with Pure HTML &amp; CSS</title>
      <dc:creator>iDev-Games</dc:creator>
      <pubDate>Fri, 29 May 2026 20:30:10 +0000</pubDate>
      <link>https://dev.to/idevgames/statejs-keysjs-tutorial-build-interactive-ui-with-pure-html-css-53h</link>
      <guid>https://dev.to/idevgames/statejs-keysjs-tutorial-build-interactive-ui-with-pure-html-css-53h</guid>
      <description>&lt;p&gt;State.js gives you &lt;strong&gt;reactive state&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Keys.js gives you &lt;strong&gt;reactive keyboard input&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;Together, they let you build interactive UI, controls, and even simple games using &lt;strong&gt;only HTML attributes&lt;/strong&gt;, with no JavaScript logic.&lt;/p&gt;

&lt;p&gt;This tutorial teaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how Keys.js tracks keyboard state
&lt;/li&gt;
&lt;li&gt;how State.js reacts to it
&lt;/li&gt;
&lt;li&gt;how to bind keys to state
&lt;/li&gt;
&lt;li&gt;how to build interactive UI
&lt;/li&gt;
&lt;li&gt;how to animate with CSS
&lt;/li&gt;
&lt;li&gt;how to build a small “move the box” demo
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s go.&lt;/p&gt;


&lt;h2&gt;
  
  
  ⭐ 1. What Keys.js Actually Does
&lt;/h2&gt;

&lt;p&gt;Keys.js listens to keyboard events and exposes them as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CSS variables&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTML attributes&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;classes&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-keys&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keys.js automatically creates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;--keys-a&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1 or &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="na"&gt;--keys-space&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1 or &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="na"&gt;--keys-last&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And adds classes like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.keys-a&lt;/span&gt;
&lt;span class="nc"&gt;.keys-space&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Learn more: &lt;strong&gt;Keys.js basics&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 2. What State.js Does With That
&lt;/h2&gt;

&lt;p&gt;State.js can react to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSS variables
&lt;/li&gt;
&lt;li&gt;attributes
&lt;/li&gt;
&lt;li&gt;events
&lt;/li&gt;
&lt;li&gt;conditions
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So when Keys.js updates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;--keys-left&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;State.js can use that to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;update state
&lt;/li&gt;
&lt;li&gt;change classes
&lt;/li&gt;
&lt;li&gt;animate with CSS
&lt;/li&gt;
&lt;li&gt;move elements
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the &lt;strong&gt;reactive input pipeline&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Keyboard → Keys.js → CSS variables → State.js → UI&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ⭐ 3. Basic Setup
&lt;/h2&gt;

&lt;p&gt;Include both libraries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/@idevgames/state-js/src/state.min.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/@idevgames/keys-js/src/keys.min.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the Keys.js root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-keys&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the entire page reacts to keyboard input.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 4. Detecting Key Presses with CSS
&lt;/h2&gt;

&lt;p&gt;Let’s show when the user presses the spacebar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"indicator"&lt;/span&gt;
     &lt;span class="na"&gt;data-keys&lt;/span&gt;
     &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-state-class=&lt;/span&gt;&lt;span class="s"&gt;"active: keys.space"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Press SPACE
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explanation:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;data-keys&lt;/code&gt; → enable Keys.js
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;keys.space&lt;/code&gt; → true when space is pressed
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-state-class="active: keys.space"&lt;/code&gt; → add &lt;code&gt;.active&lt;/code&gt; when pressed
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CSS:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.indicator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#444&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="m"&gt;0.2s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.indicator.active&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#4caf50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a &lt;strong&gt;reactive UI element&lt;/strong&gt; driven by keyboard input.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 5. Using Keys to Change State
&lt;/h2&gt;

&lt;p&gt;Let’s increment a counter when the user presses &lt;strong&gt;ArrowUp&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"counter"&lt;/span&gt;
     &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-count=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-on=&lt;/span&gt;&lt;span class="s"&gt;"keys.arrowup =&amp;gt; count += 1"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-text=&lt;/span&gt;&lt;span class="s"&gt;"Count: {count}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What happens:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Keys.js fires a &lt;code&gt;keys.arrowup&lt;/code&gt; event
&lt;/li&gt;
&lt;li&gt;State.js runs &lt;code&gt;count += 1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;UI updates automatically
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the State.js event system in action.&lt;/p&gt;

&lt;p&gt;Learn more: &lt;strong&gt;State.js event system&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 6. Using Keys to Move an Element (No JS Logic)
&lt;/h2&gt;

&lt;p&gt;Let’s build a simple “move the box” demo.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;HTML&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"player"&lt;/span&gt;
     &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-x=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt;
     &lt;span class="na"&gt;data-y=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-on=&lt;/span&gt;&lt;span class="s"&gt;"
       keys.arrowleft =&amp;gt; x -= 5;
       keys.arrowright =&amp;gt; x += 5;
       keys.arrowup =&amp;gt; y -= 5;
       keys.arrowdown =&amp;gt; y += 5
     "&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;CSS&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#player&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;dodgerblue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--state-x&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--state-y&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What’s happening:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Keys.js detects arrow keys
&lt;/li&gt;
&lt;li&gt;State.js updates &lt;code&gt;data-x&lt;/code&gt; and &lt;code&gt;data-y&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;CSS moves the element using transforms
&lt;/li&gt;
&lt;li&gt;No JavaScript logic
&lt;/li&gt;
&lt;li&gt;No game loop
&lt;/li&gt;
&lt;li&gt;No re-renders
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is &lt;strong&gt;DOM-native movement&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 7. Smooth Movement (Holding Keys)
&lt;/h2&gt;

&lt;p&gt;Keys.js exposes “held down” state as CSS variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;--keys-arrowleft&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use autofire to move continuously:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"player"&lt;/span&gt;
     &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-x=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt;
     &lt;span class="na"&gt;data-y=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-autofire=&lt;/span&gt;&lt;span class="s"&gt;"
       if keys.arrowleft then x -= 3 every 16ms;
       if keys.arrowright then x += 3 every 16ms;
       if keys.arrowup then y -= 3 every 16ms;
       if keys.arrowdown then y += 3 every 16ms
     "&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates &lt;strong&gt;smooth WASD/arrow movement&lt;/strong&gt; without JS.&lt;/p&gt;

&lt;p&gt;Learn more: &lt;strong&gt;State.js intervals&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 8. Using Keys to Trigger Animations
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"box"&lt;/span&gt;
     &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-state-class=&lt;/span&gt;&lt;span class="s"&gt;"jump: keys.space"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#box&lt;/span&gt;&lt;span class="nc"&gt;.jump&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;jump&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pressing space triggers a CSS animation.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 9. Using Keys to Toggle UI
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"menu"&lt;/span&gt;
     &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-open=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-on=&lt;/span&gt;&lt;span class="s"&gt;"keys.escape =&amp;gt; open = !open"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-class=&lt;/span&gt;&lt;span class="s"&gt;"visible: open"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Menu Content
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Press ESC → open/close menu.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 10. Full Example — Move a Box + Change Color + Show Key
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-keys&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"player"&lt;/span&gt;
     &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-x=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt;
     &lt;span class="na"&gt;data-y=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt;
     &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"blue"&lt;/span&gt;

     &lt;span class="na"&gt;data-state-on=&lt;/span&gt;&lt;span class="s"&gt;"
       keys.arrowleft =&amp;gt; x -= 5;
       keys.arrowright =&amp;gt; x += 5;
       keys.arrowup =&amp;gt; y -= 5;
       keys.arrowdown =&amp;gt; y += 5;
       keys.space =&amp;gt; color = 'red'
     "&lt;/span&gt;

     &lt;span class="na"&gt;data-state-style=&lt;/span&gt;&lt;span class="s"&gt;"background: {color}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"info"&lt;/span&gt;
     &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-state-text=&lt;/span&gt;&lt;span class="s"&gt;"Last key: {keys.last}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#player&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--state-x&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--state-y&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;movement
&lt;/li&gt;
&lt;li&gt;color change
&lt;/li&gt;
&lt;li&gt;last key display
&lt;/li&gt;
&lt;li&gt;all reactive
&lt;/li&gt;
&lt;li&gt;all declarative
&lt;/li&gt;
&lt;li&gt;zero JS logic
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⭐ Why State.js + Keys.js Works So Well
&lt;/h2&gt;

&lt;p&gt;Because they follow the same philosophy:&lt;/p&gt;

&lt;h3&gt;
  
  
  ✔ HTML = structure
&lt;/h3&gt;

&lt;h3&gt;
  
  
  ✔ CSS = behavior
&lt;/h3&gt;

&lt;h3&gt;
  
  
  ✔ Attributes = API
&lt;/h3&gt;

&lt;h3&gt;
  
  
  ✔ JS = engine, not authoring
&lt;/h3&gt;

&lt;h3&gt;
  
  
  ✔ Zero build step
&lt;/h3&gt;

&lt;h3&gt;
  
  
  ✔ Zero dependencies
&lt;/h3&gt;

&lt;h3&gt;
  
  
  ✔ Browser-native
&lt;/h3&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>beginners</category>
      <category>opensource</category>
    </item>
    <item>
      <title>State.js Event System - The Complete Beginner’s Guide</title>
      <dc:creator>iDev-Games</dc:creator>
      <pubDate>Fri, 29 May 2026 20:15:23 +0000</pubDate>
      <link>https://dev.to/idevgames/statejs-event-system-the-complete-beginners-guide-2a09</link>
      <guid>https://dev.to/idevgames/statejs-event-system-the-complete-beginners-guide-2a09</guid>
      <description>&lt;p&gt;State.js introduces a new way to build reactive UI:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;HTML holds the data.&lt;br&gt;&lt;br&gt;
CSS reacts to the data.&lt;br&gt;&lt;br&gt;
Events change the data.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This tutorial explains how State.js listens to events, how you trigger state changes, and how to build interactive UI without writing JavaScript logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 1. What Is a State.js Event?
&lt;/h2&gt;

&lt;p&gt;A State.js event is simply:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;strong&gt;DOM event&lt;/strong&gt; (click, input, mouseover, keydown, etc.)&lt;/li&gt;
&lt;li&gt;connected to a &lt;strong&gt;state mutation&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;written declaratively in HTML&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-count=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-on=&lt;/span&gt;&lt;span class="s"&gt;"click =&amp;gt; count += 1"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-text=&lt;/span&gt;&lt;span class="s"&gt;"Count: {count}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you click the element:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;count&lt;/code&gt; increases
&lt;/li&gt;
&lt;li&gt;State.js updates the attribute
&lt;/li&gt;
&lt;li&gt;CSS variables update
&lt;/li&gt;
&lt;li&gt;the text updates
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All without JavaScript logic.&lt;/p&gt;

&lt;p&gt;Learn more: &lt;strong&gt;State.js triggers&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 2. The &lt;code&gt;data-state-on&lt;/code&gt; Attribute
&lt;/h2&gt;

&lt;p&gt;This is the core of the event system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-active=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-on=&lt;/span&gt;&lt;span class="s"&gt;"click =&amp;gt; active = !active"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This toggles the &lt;code&gt;data-active&lt;/code&gt; attribute every time the element is clicked.&lt;/p&gt;

&lt;p&gt;State.js then:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;updates CSS variables
&lt;/li&gt;
&lt;li&gt;updates any bound text
&lt;/li&gt;
&lt;li&gt;updates any reactive classes
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⭐ 3. Listening to Any DOM Event
&lt;/h2&gt;

&lt;p&gt;You can listen to &lt;em&gt;any&lt;/em&gt; event the browser supports.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Click&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;data-state-on="click =&amp;gt; count += 1"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Input&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;data-state-on="input =&amp;gt; value = event.target.value"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Mouseover&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;data-state-on="mouseover =&amp;gt; hovered = true"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Mouseout&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;data-state-on="mouseout =&amp;gt; hovered = false"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Keydown&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;data-state-on="keydown =&amp;gt; key = event.key"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;State.js doesn’t invent new events — it uses the browser’s native ones.&lt;/p&gt;

&lt;p&gt;Learn more: &lt;strong&gt;Event expressions&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 4. Using Event Data (&lt;code&gt;event&lt;/code&gt;)
&lt;/h2&gt;

&lt;p&gt;State.js exposes the event object as &lt;code&gt;event&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Example: capture the clicked element’s text.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-last=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;
     &lt;span class="na"&gt;data-state-on=&lt;/span&gt;&lt;span class="s"&gt;"click =&amp;gt; last = event.target.textContent"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-text=&lt;/span&gt;&lt;span class="s"&gt;"Last clicked: {last}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example: track mouse position.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-x=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
     &lt;span class="na"&gt;data-y=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-on=&lt;/span&gt;&lt;span class="s"&gt;"mousemove =&amp;gt; x = event.clientX; y = event.clientY"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-text=&lt;/span&gt;&lt;span class="s"&gt;"X: {x}, Y: {y}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⭐ 5. Updating Another Element’s State
&lt;/h2&gt;

&lt;p&gt;Use &lt;code&gt;data-state-target&lt;/code&gt; to update a different element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;
  &lt;span class="na"&gt;data-state-trigger&lt;/span&gt;
  &lt;span class="na"&gt;data-state-target=&lt;/span&gt;&lt;span class="s"&gt;"#box"&lt;/span&gt;
  &lt;span class="na"&gt;data-state-on=&lt;/span&gt;&lt;span class="s"&gt;"click =&amp;gt; color = 'red'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Make Red
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"box"&lt;/span&gt;
     &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"blue"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-class=&lt;/span&gt;&lt;span class="s"&gt;"red: color == 'red'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the State.js equivalent of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React props
&lt;/li&gt;
&lt;li&gt;Vue emits
&lt;/li&gt;
&lt;li&gt;Svelte dispatch
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But simpler.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 6. Multiple Event Handlers
&lt;/h2&gt;

&lt;p&gt;You can chain multiple events:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-state-on=&lt;/span&gt;&lt;span class="s"&gt;"
       click =&amp;gt; count += 1;
       mouseover =&amp;gt; hovered = true;
       mouseout =&amp;gt; hovered = false
     "&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each event runs its own expression.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 7. Using Events to Add/Remove Classes
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-active=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-on=&lt;/span&gt;&lt;span class="s"&gt;"click =&amp;gt; active = !active"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-class=&lt;/span&gt;&lt;span class="s"&gt;"active: active"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This toggles a class with no JavaScript.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 8. Using Events to Drive CSS Animations
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-state-on=&lt;/span&gt;&lt;span class="s"&gt;"click =&amp;gt; animate = true"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-class=&lt;/span&gt;&lt;span class="s"&gt;"pop: animate"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.pop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pop&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how you build interactive UI without JS logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 9. Building a Mini App with Events
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;
     &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-count=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-on=&lt;/span&gt;&lt;span class="s"&gt;"click =&amp;gt; count += 1"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-text=&lt;/span&gt;&lt;span class="s"&gt;"Clicked {count} times"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a complete app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reactive state
&lt;/li&gt;
&lt;li&gt;reactive text
&lt;/li&gt;
&lt;li&gt;event-driven logic
&lt;/li&gt;
&lt;li&gt;no JavaScript
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the &lt;strong&gt;State.js mental model&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 10. Why the Event System Matters
&lt;/h2&gt;

&lt;p&gt;Because it replaces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React’s &lt;code&gt;onClick={() =&amp;gt; setCount(count + 1)}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Vue’s &lt;code&gt;@click="count++"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Svelte’s &lt;code&gt;on:click={() =&amp;gt; count++}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;data-state-on="click =&amp;gt; count += 1"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No JS.&lt;br&gt;&lt;br&gt;
No framework.&lt;br&gt;&lt;br&gt;
No re-renders.&lt;br&gt;&lt;br&gt;
No hydration.&lt;br&gt;&lt;br&gt;
No build step.&lt;/p&gt;

&lt;p&gt;This is the &lt;strong&gt;State.js philosophy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Learn more: &lt;strong&gt;State.js architecture&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>⭐ State.js Basics — Learn CSS‑Driven Reactivity in 10 Minutes</title>
      <dc:creator>iDev-Games</dc:creator>
      <pubDate>Fri, 29 May 2026 20:05:15 +0000</pubDate>
      <link>https://dev.to/idevgames/statejs-basics-learn-css-driven-reactivity-in-10-minutes-3m80</link>
      <guid>https://dev.to/idevgames/statejs-basics-learn-css-driven-reactivity-in-10-minutes-3m80</guid>
      <description>&lt;p&gt;State.js looks simple — just HTML attributes — but it introduces a &lt;strong&gt;new mental model&lt;/strong&gt; for building UI:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;HTML holds the data.&lt;br&gt;&lt;br&gt;
CSS reacts to the data.&lt;br&gt;&lt;br&gt;
State.js keeps them in sync.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you’re used to React, Vue, or Svelte, this feels strange at first.&lt;br&gt;&lt;br&gt;
If you’re used to CSS, this feels like “why didn’t CSS always work like this?”&lt;/p&gt;

&lt;p&gt;This tutorial will teach you the core ideas behind State.js so you can build reactive UI without JavaScript logic, without a framework, and without a build step.&lt;/p&gt;


&lt;h2&gt;
  
  
  ⭐ 1. What State.js Actually Does
&lt;/h2&gt;

&lt;p&gt;State.js turns HTML attributes into &lt;strong&gt;live CSS variables&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-state&lt;/span&gt; &lt;span class="na"&gt;data-count=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;State.js automatically exposes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;--state-count&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;data-count&lt;/code&gt; changes, the CSS variable updates instantly.&lt;/p&gt;

&lt;p&gt;This is the foundation of everything.&lt;/p&gt;

&lt;p&gt;Learn more: &lt;strong&gt;Reactive attributes&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 2. Your First Reactive Element
&lt;/h2&gt;

&lt;p&gt;Let’s make a simple counter.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;HTML&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"counter"&lt;/span&gt;
     &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-count=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-text=&lt;/span&gt;&lt;span class="s"&gt;"Count: {count}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What’s happening?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;data-state&lt;/code&gt; → activates State.js
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-count="0"&lt;/code&gt; → creates &lt;code&gt;--state-count: 0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-state-text="Count: {count}"&lt;/code&gt; → binds text to the value
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;State.js replaces &lt;code&gt;{count}&lt;/code&gt; with the live value.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 3. Updating State with Triggers
&lt;/h2&gt;

&lt;p&gt;Add a button that increments the counter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;
  &lt;span class="na"&gt;data-state-trigger&lt;/span&gt;
  &lt;span class="na"&gt;data-state-target=&lt;/span&gt;&lt;span class="s"&gt;"#counter"&lt;/span&gt;
  &lt;span class="na"&gt;data-state-attr=&lt;/span&gt;&lt;span class="s"&gt;"count"&lt;/span&gt;
  &lt;span class="na"&gt;data-state-increment=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  +1
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What this means:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;data-state-trigger&lt;/code&gt; → this element performs an action
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-state-target="#counter"&lt;/code&gt; → update that element
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-state-attr="count"&lt;/code&gt; → update the &lt;code&gt;data-count&lt;/code&gt; attribute
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-state-increment="1"&lt;/code&gt; → add 1
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Clicking the button updates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the attribute
&lt;/li&gt;
&lt;li&gt;the CSS variable
&lt;/li&gt;
&lt;li&gt;the text
&lt;/li&gt;
&lt;li&gt;all automatically
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Learn more: &lt;strong&gt;Triggers&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 4. Styling with CSS Variables
&lt;/h2&gt;

&lt;p&gt;Because State.js exposes attributes as CSS variables, you can style reactively:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#counter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;hsl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--state-count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="m"&gt;80%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the count increases, the color changes.&lt;/p&gt;

&lt;p&gt;No JS.&lt;br&gt;&lt;br&gt;
No re-renders.&lt;br&gt;&lt;br&gt;
Just CSS reacting to state.&lt;/p&gt;

&lt;p&gt;Learn more: &lt;strong&gt;CSS variable projection&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  ⭐ 5. Conditions (Reactive Logic in HTML)
&lt;/h2&gt;

&lt;p&gt;Let’s change the background when the count reaches 5.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"counter"&lt;/span&gt;
     &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-count=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-class=&lt;/span&gt;&lt;span class="s"&gt;"big: count &amp;gt;= 5"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-text=&lt;/span&gt;&lt;span class="s"&gt;"Count: {count}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This adds the class &lt;code&gt;.big&lt;/code&gt; when the condition is true.&lt;/p&gt;

&lt;h3&gt;
  
  
  CSS:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.big&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;gold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Learn more: &lt;strong&gt;Conditions&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 6. Autofire (State.js “Game Loop”)
&lt;/h2&gt;

&lt;p&gt;State.js can update values on an interval:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-time=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-autofire=&lt;/span&gt;&lt;span class="s"&gt;"time += 1 every 100ms"&lt;/span&gt;
     &lt;span class="na"&gt;data-state-text=&lt;/span&gt;&lt;span class="s"&gt;"Time: {time}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a &lt;strong&gt;reactive timer&lt;/strong&gt; with no JavaScript.&lt;/p&gt;

&lt;p&gt;Learn more: &lt;strong&gt;Intervals&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 7. Two-Way Binding (Forms Without JS)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"range"&lt;/span&gt;
       &lt;span class="na"&gt;data-state&lt;/span&gt;
       &lt;span class="na"&gt;data-value=&lt;/span&gt;&lt;span class="s"&gt;"50"&lt;/span&gt;
       &lt;span class="na"&gt;data-state-bind=&lt;/span&gt;&lt;span class="s"&gt;"value"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-state&lt;/span&gt;
     &lt;span class="na"&gt;data-state-text=&lt;/span&gt;&lt;span class="s"&gt;"Value: {value}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Moving the slider updates the text automatically.&lt;/p&gt;

&lt;p&gt;Learn more: &lt;strong&gt;Binding&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 8. Putting It All Together — A Mini App
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt; &lt;span class="na"&gt;data-state&lt;/span&gt; &lt;span class="na"&gt;data-count=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;data-state-text=&lt;/span&gt;&lt;span class="s"&gt;"Count: {count}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;
    &lt;span class="na"&gt;data-state-trigger&lt;/span&gt;
    &lt;span class="na"&gt;data-state-target=&lt;/span&gt;&lt;span class="s"&gt;"#app"&lt;/span&gt;
    &lt;span class="na"&gt;data-state-attr=&lt;/span&gt;&lt;span class="s"&gt;"count"&lt;/span&gt;
    &lt;span class="na"&gt;data-state-increment=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    +1
  &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;
    &lt;span class="na"&gt;data-state-trigger&lt;/span&gt;
    &lt;span class="na"&gt;data-state-target=&lt;/span&gt;&lt;span class="s"&gt;"#app"&lt;/span&gt;
    &lt;span class="na"&gt;data-state-attr=&lt;/span&gt;&lt;span class="s"&gt;"count"&lt;/span&gt;
    &lt;span class="na"&gt;data-state-increment=&lt;/span&gt;&lt;span class="s"&gt;"-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    -1
  &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-state-class=&lt;/span&gt;&lt;span class="s"&gt;"warning: count &amp;lt; 0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Count is negative!&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What you get:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;reactive text
&lt;/li&gt;
&lt;li&gt;reactive classes
&lt;/li&gt;
&lt;li&gt;reactive styling
&lt;/li&gt;
&lt;li&gt;reactive state
&lt;/li&gt;
&lt;li&gt;no JavaScript logic
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the &lt;strong&gt;State.js mental model&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⭐ 9. Why This Matters
&lt;/h2&gt;

&lt;p&gt;State.js gives you:&lt;/p&gt;

&lt;h3&gt;
  
  
  ✔ Reactivity without JavaScript
&lt;/h3&gt;

&lt;p&gt;No functions.&lt;br&gt;&lt;br&gt;
No hooks.&lt;br&gt;&lt;br&gt;
No re-renders.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✔ Components without frameworks
&lt;/h3&gt;

&lt;p&gt;Just templates + includes.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✔ State without state management libraries
&lt;/h3&gt;

&lt;p&gt;Attributes &lt;em&gt;are&lt;/em&gt; the state.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✔ UI logic without JS
&lt;/h3&gt;

&lt;p&gt;CSS handles behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✔ Zero build step
&lt;/h3&gt;

&lt;p&gt;Works in plain HTML.&lt;/p&gt;

&lt;p&gt;This is why people say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“It feels like something CSS should have done.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because State.js makes the browser behave the way developers &lt;em&gt;wish&lt;/em&gt; it behaved.&lt;/p&gt;

</description>
      <category>css</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>State.js Tutorial: Creating Reusable UI Components with Pure CSS Reactivity</title>
      <dc:creator>iDev-Games</dc:creator>
      <pubDate>Wed, 27 May 2026 21:39:19 +0000</pubDate>
      <link>https://dev.to/idevgames/statejs-tutorial-creating-reusable-ui-components-with-pure-css-reactivity-3b56</link>
      <guid>https://dev.to/idevgames/statejs-tutorial-creating-reusable-ui-components-with-pure-css-reactivity-3b56</guid>
      <description>&lt;p&gt;Modern frontend frameworks treat components as JavaScript functions, classes, or compiled files.&lt;br&gt;&lt;br&gt;
But what if components didn’t need JavaScript at all?&lt;/p&gt;

&lt;p&gt;What if components were built from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTML templates&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSS for behavior and visuals&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State.js attributes for reactivity&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…with &lt;strong&gt;no JS logic, no virtual DOM, and no build step&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;That’s exactly what &lt;strong&gt;State.js&lt;/strong&gt; enables.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/iDev-Games/State-JS" rel="noopener noreferrer"&gt;State.js&lt;/a&gt; turns HTML attributes into &lt;strong&gt;reactive CSS variables&lt;/strong&gt;, letting you build fully reactive, reusable UI components using nothing but HTML + CSS.&lt;/p&gt;

&lt;p&gt;In this article, you’ll learn how &lt;strong&gt;State.js components actually work&lt;/strong&gt;.&lt;/p&gt;


&lt;h1&gt;
  
  
  ⭐ &lt;strong&gt;What Is a Component in State.js?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;In React, a component is a function.&lt;br&gt;&lt;br&gt;
In Vue, it’s an object.&lt;br&gt;&lt;br&gt;
In Svelte, it’s a compiled file.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;State.js&lt;/strong&gt;, a component is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A reusable HTML template that becomes reactive when included with &lt;code&gt;data-state-include&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A component is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;defined once
&lt;/li&gt;
&lt;li&gt;cloned anywhere
&lt;/li&gt;
&lt;li&gt;customized via attributes
&lt;/li&gt;
&lt;li&gt;reactive automatically
&lt;/li&gt;
&lt;li&gt;fully encapsulated
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No JavaScript logic.&lt;br&gt;&lt;br&gt;
No rendering engine.&lt;br&gt;&lt;br&gt;
No framework runtime.&lt;/p&gt;

&lt;p&gt;Just &lt;strong&gt;HTML + CSS + State.js&lt;/strong&gt;.&lt;/p&gt;


&lt;h1&gt;
  
  
  ⭐ &lt;strong&gt;Example: A Reusable &lt;code&gt;&amp;lt;char-card&amp;gt;&lt;/code&gt; Component&lt;/strong&gt;
&lt;/h1&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;1. Define the component once&lt;/strong&gt;
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"char-card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"char-card"&lt;/span&gt; &lt;span class="na"&gt;data-state&lt;/span&gt; &lt;span class="na"&gt;data-hp=&lt;/span&gt;&lt;span class="s"&gt;"20"&lt;/span&gt; &lt;span class="na"&gt;data-hp-max=&lt;/span&gt;&lt;span class="s"&gt;"20"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt; &lt;span class="na"&gt;data-state-display=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bar"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fill"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"width: var(--state-hp-percent)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;data-state-trigger&lt;/span&gt; &lt;span class="na"&gt;data-state-attr=&lt;/span&gt;&lt;span class="s"&gt;"hp"&lt;/span&gt; &lt;span class="na"&gt;data-state-increment=&lt;/span&gt;&lt;span class="s"&gt;"-5"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      Damage
    &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This is the &lt;strong&gt;component definition&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;State.js automatically exposes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--state-hp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--state-hp-max&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--state-hp-percent&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These update reactively whenever attributes change.&lt;/p&gt;


&lt;h1&gt;
  
  
  ⭐ &lt;strong&gt;2. Use the component anywhere&lt;/strong&gt;
&lt;/h1&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-state-include=&lt;/span&gt;&lt;span class="s"&gt;"#char-card"&lt;/span&gt;
     &lt;span class="na"&gt;data-name=&lt;/span&gt;&lt;span class="s"&gt;"Warrior"&lt;/span&gt;
     &lt;span class="na"&gt;data-hp=&lt;/span&gt;&lt;span class="s"&gt;"18"&lt;/span&gt;
     &lt;span class="na"&gt;data-hp-max=&lt;/span&gt;&lt;span class="s"&gt;"20"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-state-include=&lt;/span&gt;&lt;span class="s"&gt;"#char-card"&lt;/span&gt;
     &lt;span class="na"&gt;data-name=&lt;/span&gt;&lt;span class="s"&gt;"Mage"&lt;/span&gt;
     &lt;span class="na"&gt;data-hp=&lt;/span&gt;&lt;span class="s"&gt;"9"&lt;/span&gt;
     &lt;span class="na"&gt;data-hp-max=&lt;/span&gt;&lt;span class="s"&gt;"12"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Each instance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clones the template
&lt;/li&gt;
&lt;li&gt;merges your attributes
&lt;/li&gt;
&lt;li&gt;becomes a fully reactive component
&lt;/li&gt;
&lt;li&gt;auto-binds triggers to its own state
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the State.js equivalent of &lt;strong&gt;props&lt;/strong&gt;, but simpler.&lt;/p&gt;


&lt;h1&gt;
  
  
  ⭐ &lt;strong&gt;CSS Drives the Component’s Behavior&lt;/strong&gt;
&lt;/h1&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.char-card&lt;/span&gt; &lt;span class="nc"&gt;.bar&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#333&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.char-card&lt;/span&gt; &lt;span class="nc"&gt;.fill&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#4caf50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--state-hp-percent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;CSS handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;animation
&lt;/li&gt;
&lt;li&gt;interpolation
&lt;/li&gt;
&lt;li&gt;transitions
&lt;/li&gt;
&lt;li&gt;layout
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;State.js handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;state changes
&lt;/li&gt;
&lt;li&gt;variable updates
&lt;/li&gt;
&lt;li&gt;triggers
&lt;/li&gt;
&lt;li&gt;reactivity
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is &lt;strong&gt;CSS‑reactive architecture&lt;/strong&gt;.&lt;/p&gt;


&lt;h1&gt;
  
  
  ⭐ &lt;strong&gt;Updating the Component&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Inside the component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;data-state-trigger&lt;/span&gt; &lt;span class="na"&gt;data-state-attr=&lt;/span&gt;&lt;span class="s"&gt;"hp"&lt;/span&gt; &lt;span class="na"&gt;data-state-increment=&lt;/span&gt;&lt;span class="s"&gt;"-5"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Damage
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When clicked:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;data-hp&lt;/code&gt; decreases
&lt;/li&gt;
&lt;li&gt;State.js updates &lt;code&gt;--state-hp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;CSS recalculates &lt;code&gt;--state-hp-percent&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The bar animates automatically
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is &lt;strong&gt;reactivity without JavaScript logic&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  ⭐ &lt;strong&gt;Why This Works&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;State.js turns HTML attributes into &lt;strong&gt;live CSS variables&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;CSS handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;layout
&lt;/li&gt;
&lt;li&gt;animation
&lt;/li&gt;
&lt;li&gt;transitions
&lt;/li&gt;
&lt;li&gt;transforms
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;State.js handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;state
&lt;/li&gt;
&lt;li&gt;triggers
&lt;/li&gt;
&lt;li&gt;conditions
&lt;/li&gt;
&lt;li&gt;intervals
&lt;/li&gt;
&lt;li&gt;reactivity
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, they form a &lt;strong&gt;browser‑native component system&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  ⭐ &lt;strong&gt;Why This Is a Big Deal&lt;/strong&gt;
&lt;/h1&gt;

&lt;h3&gt;
  
  
  ✔ Zero JavaScript logic
&lt;/h3&gt;

&lt;p&gt;Your component logic lives in HTML + CSS.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✔ Zero framework runtime
&lt;/h3&gt;

&lt;p&gt;No virtual DOM.&lt;br&gt;&lt;br&gt;
No hydration.&lt;br&gt;&lt;br&gt;
No re-renders.&lt;/p&gt;
&lt;h3&gt;
  
  
  ✔ Zero build step
&lt;/h3&gt;

&lt;p&gt;Works in plain HTML files.&lt;/p&gt;
&lt;h3&gt;
  
  
  ✔ Fully portable components
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;&amp;lt;char-card&amp;gt;&lt;/code&gt; works anywhere HTML works.&lt;/p&gt;
&lt;h3&gt;
  
  
  ✔ Native browser performance
&lt;/h3&gt;

&lt;p&gt;CSS is GPU‑accelerated and instant.&lt;/p&gt;
&lt;h3&gt;
  
  
  ✔ Auto‑binding triggers
&lt;/h3&gt;

&lt;p&gt;Buttons inside the template automatically bind to the nearest &lt;code&gt;[data-state]&lt;/code&gt; parent.&lt;/p&gt;


&lt;h1&gt;
  
  
  ⭐ &lt;strong&gt;Component API Design&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;You can define your own “props” using attributes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-state-include=&lt;/span&gt;&lt;span class="s"&gt;"#char-card"&lt;/span&gt;
     &lt;span class="na"&gt;data-name=&lt;/span&gt;&lt;span class="s"&gt;"Rogue"&lt;/span&gt;
     &lt;span class="na"&gt;data-hp=&lt;/span&gt;&lt;span class="s"&gt;"12"&lt;/span&gt;
     &lt;span class="na"&gt;data-hp-max=&lt;/span&gt;&lt;span class="s"&gt;"14"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or add more:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-state-include=&lt;/span&gt;&lt;span class="s"&gt;"#char-card"&lt;/span&gt;
     &lt;span class="na"&gt;data-name=&lt;/span&gt;&lt;span class="s"&gt;"Cleric"&lt;/span&gt;
     &lt;span class="na"&gt;data-hp=&lt;/span&gt;&lt;span class="s"&gt;"14"&lt;/span&gt;
     &lt;span class="na"&gt;data-hp-max=&lt;/span&gt;&lt;span class="s"&gt;"16"&lt;/span&gt;
     &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"blue"&lt;/span&gt;
     &lt;span class="na"&gt;data-low=&lt;/span&gt;&lt;span class="s"&gt;"red"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;State.js exposes them all as CSS variables.&lt;/p&gt;




&lt;h1&gt;
  
  
  ⭐ &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/iDev-Games/State-JS" rel="noopener noreferrer"&gt;State.js&lt;/a&gt; lets you build components using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTML for structure&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSS for behavior&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State.js for reactivity&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This creates a new category of UI architecture:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;CSS‑Reactive Components&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Components powered by HTML templates, CSS variables, and declarative reactivity — not JavaScript logic.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you want lightweight, portable, framework‑free UI, this pattern is a game changer.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>css</category>
      <category>html</category>
      <category>webdev</category>
    </item>
    <item>
      <title>CSS Reactive Frameworks: Why the Future of UI Flows Through CSS Instead of JavaScript</title>
      <dc:creator>iDev-Games</dc:creator>
      <pubDate>Wed, 27 May 2026 11:54:22 +0000</pubDate>
      <link>https://dev.to/idevgames/css-reactive-frameworks-why-the-future-of-ui-flows-through-css-instead-of-javascript-4179</link>
      <guid>https://dev.to/idevgames/css-reactive-frameworks-why-the-future-of-ui-flows-through-css-instead-of-javascript-4179</guid>
      <description>&lt;p&gt;Modern frontend development has a contradiction at its core.&lt;/p&gt;

&lt;p&gt;We tell developers that rich interactivity requires layers of abstraction:&lt;br&gt;
virtual DOMs, hydration pipelines, reactive hooks, compiler stages, bundlers, state containers, and increasingly complex rendering architectures.&lt;/p&gt;

&lt;p&gt;Then someone ships a fully interactive, real-time simulation from a single local HTML file with almost no custom JavaScript — and it runs flawlessly at 60 FPS.&lt;/p&gt;

&lt;p&gt;That contradiction is the “No-JS” paradox.&lt;/p&gt;

&lt;p&gt;And it exposes something the industry has slowly forgotten:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The browser is already a reactive engine.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Frameworks didn’t invent reactivity. Browsers had it from the beginning.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/iDev-Games/State-JS" rel="noopener noreferrer"&gt;State.js&lt;/a&gt; simply stops fighting the browser’s architecture and starts working with it instead.&lt;/p&gt;


&lt;h1&gt;
  
  
  We Built an Entire Industry Around Re-Rendering
&lt;/h1&gt;

&lt;p&gt;For the last decade, frontend engineering has been dominated by one assumption:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Application state belongs exclusively to JavaScript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This belief shaped the modern web stack.&lt;/p&gt;

&lt;p&gt;Need to update text? Trigger a render cycle.&lt;br&gt;&lt;br&gt;
Need to animate UI? Route it through component state.&lt;br&gt;&lt;br&gt;
Need interactivity? Build a synchronization layer between memory and the DOM.&lt;/p&gt;

&lt;p&gt;The result is an ecosystem where developers routinely ship megabytes of tooling just to keep application data synchronized with elements the browser already knows how to update natively.&lt;/p&gt;

&lt;p&gt;Modern frameworks treat the DOM as a dumb output target — something to be diffed, patched, reconciled, hydrated, and rebuilt.&lt;/p&gt;

&lt;p&gt;But the DOM was never dumb.&lt;/p&gt;

&lt;p&gt;The browser’s rendering engine is one of the most optimized reactive systems ever created.&lt;/p&gt;

&lt;p&gt;It already performs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dependency resolution&lt;/li&gt;
&lt;li&gt;style recalculation&lt;/li&gt;
&lt;li&gt;layout propagation&lt;/li&gt;
&lt;li&gt;compositing&lt;/li&gt;
&lt;li&gt;animation timing&lt;/li&gt;
&lt;li&gt;GPU acceleration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The web platform solved reactivity years ago.&lt;/p&gt;

&lt;p&gt;Most frameworks simply rebuilt it in JavaScript.&lt;/p&gt;


&lt;h1&gt;
  
  
  The Core Idea Behind CSS Reactive Frameworks
&lt;/h1&gt;

&lt;p&gt;State.js introduces a different model.&lt;/p&gt;

&lt;p&gt;Instead of routing UI updates through JavaScript rendering logic, it exposes application state directly to CSS through native browser variables.&lt;/p&gt;

&lt;p&gt;Your markup becomes the source of truth.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"colony"&lt;/span&gt;
  &lt;span class="na"&gt;data-state&lt;/span&gt;
  &lt;span class="na"&gt;data-state-watch=&lt;/span&gt;&lt;span class="s"&gt;"spores,bio,mut,haz"&lt;/span&gt;
  &lt;span class="na"&gt;data-spores=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt;
  &lt;span class="na"&gt;data-bio=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
  &lt;span class="na"&gt;data-mut=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
  &lt;span class="na"&gt;data-haz=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When attributes change, State.js maps them directly into CSS custom properties:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;--state-spores&lt;/span&gt;
&lt;span class="nt"&gt;--state-bio&lt;/span&gt;
&lt;span class="nt"&gt;--state-mut&lt;/span&gt;
&lt;span class="nt"&gt;--state-haz&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At that point, JavaScript’s job is effectively finished.&lt;/p&gt;

&lt;p&gt;The browser takes over.&lt;/p&gt;

&lt;p&gt;CSS becomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the rendering layer&lt;/li&gt;
&lt;li&gt;the calculation layer&lt;/li&gt;
&lt;li&gt;the reactive layer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s the paradigm shift.&lt;/p&gt;




&lt;h1&gt;
  
  
  The DOM Is Already a Database
&lt;/h1&gt;

&lt;p&gt;Traditional frameworks separate state from presentation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript owns the data&lt;/li&gt;
&lt;li&gt;The framework owns synchronization&lt;/li&gt;
&lt;li&gt;The DOM becomes a visual projection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But in a CSS reactive architecture, the DOM &lt;em&gt;is&lt;/em&gt; the state container.&lt;/p&gt;

&lt;p&gt;That changes everything.&lt;/p&gt;

&lt;p&gt;Instead of hidden memory trees buried inside framework internals, state becomes visible, inspectable, and native.&lt;/p&gt;

&lt;p&gt;Open DevTools and the entire application state is sitting directly inside the markup.&lt;/p&gt;

&lt;p&gt;You can literally edit gameplay values live in the Elements panel and watch the interface react instantly.&lt;/p&gt;

&lt;p&gt;No React DevTools.&lt;br&gt;&lt;br&gt;
No framework inspectors.&lt;br&gt;&lt;br&gt;
No hidden proxy objects.&lt;br&gt;&lt;br&gt;
No hydration debugging.&lt;/p&gt;

&lt;p&gt;The browser already gives you the tooling.&lt;/p&gt;


&lt;h1&gt;
  
  
  Why CSS Reactive Systems Feel Faster
&lt;/h1&gt;

&lt;p&gt;One of the biggest performance gains comes from removing render bottlenecks entirely.&lt;/p&gt;

&lt;p&gt;In traditional frontend frameworks, a state update typically triggers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;JavaScript execution&lt;/li&gt;
&lt;li&gt;Dependency tracking&lt;/li&gt;
&lt;li&gt;Component reconciliation&lt;/li&gt;
&lt;li&gt;Virtual DOM diffing&lt;/li&gt;
&lt;li&gt;DOM patching&lt;/li&gt;
&lt;li&gt;Layout recalculation&lt;/li&gt;
&lt;li&gt;Paint/composite&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In a CSS reactive system, most of this disappears.&lt;/p&gt;

&lt;p&gt;The state changes once.&lt;/p&gt;

&lt;p&gt;The browser updates CSS variables.&lt;/p&gt;

&lt;p&gt;Everything downstream becomes native browser work.&lt;/p&gt;

&lt;p&gt;That matters because browsers optimize CSS and compositing at an extremely low level — often directly on GPU compositor threads.&lt;/p&gt;

&lt;p&gt;Animations stay smooth because the browser is doing what it was originally designed to do instead of waiting for JavaScript reconciliation loops every frame.&lt;/p&gt;


&lt;h1&gt;
  
  
  CSS Is More Powerful Than We Pretend
&lt;/h1&gt;

&lt;p&gt;Modern CSS is no longer just decorative styling.&lt;/p&gt;

&lt;p&gt;It already contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;variables&lt;/li&gt;
&lt;li&gt;math&lt;/li&gt;
&lt;li&gt;conditional logic&lt;/li&gt;
&lt;li&gt;timelines&lt;/li&gt;
&lt;li&gt;interpolation&lt;/li&gt;
&lt;li&gt;transform pipelines&lt;/li&gt;
&lt;li&gt;scroll-driven animation&lt;/li&gt;
&lt;li&gt;responsive calculations&lt;/li&gt;
&lt;li&gt;hardware acceleration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yet most developers still treat CSS like a passive skin layered on top of JavaScript applications.&lt;/p&gt;

&lt;p&gt;CSS reactive architecture flips that relationship.&lt;/p&gt;

&lt;p&gt;Instead of JavaScript commanding the interface every frame, CSS passively responds to changing data.&lt;/p&gt;

&lt;p&gt;A progress bar doesn’t need imperative width calculations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.progress-fill&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--state-spores-percent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A camera shake effect doesn’t need animation libraries.&lt;/p&gt;

&lt;p&gt;A HUD doesn’t need rerendering.&lt;/p&gt;

&lt;p&gt;A dashboard doesn’t need component invalidation.&lt;/p&gt;

&lt;p&gt;The browser already knows how to propagate visual dependencies.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Modular Micro-Library Ecosystem
&lt;/h1&gt;

&lt;p&gt;What makes this philosophy especially interesting is that it encourages modularity instead of ecosystem lock-in.&lt;/p&gt;

&lt;p&gt;Instead of one massive framework controlling everything, browser behavior can be split into focused micro-libraries that extend native capabilities.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/iDev-Games/Trig.js" rel="noopener noreferrer"&gt;Trig.js&lt;/a&gt; feeds scroll positions directly into CSS variables for cinematic scroll-driven interfaces&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/iDev-Games/Motion-JS" rel="noopener noreferrer"&gt;Motion.js&lt;/a&gt; acts as a global timing engine for timeline-driven CSS animation systems&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/iDev-Games/Keys-JS" rel="noopener noreferrer"&gt;Keys.js&lt;/a&gt; maps keyboard input directly into declarative state mutations&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/iDev-Games/Cursor-JS" rel="noopener noreferrer"&gt;Cursor.js&lt;/a&gt; introduces reactive pointer tracking without heavy event plumbing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of adopting an all-or-nothing framework ecosystem, developers compose exactly the behavior layer they need.&lt;/p&gt;

&lt;p&gt;That’s much closer to how the web was originally intended to work.&lt;/p&gt;




&lt;h1&gt;
  
  
  This Isn’t “Anti-JavaScript”
&lt;/h1&gt;

&lt;p&gt;This is an important distinction.&lt;/p&gt;

&lt;p&gt;CSS reactive architecture is not about eliminating JavaScript.&lt;/p&gt;

&lt;p&gt;It’s about redefining JavaScript’s role.&lt;/p&gt;

&lt;p&gt;JavaScript becomes a lightweight state mutator instead of a full rendering runtime.&lt;/p&gt;

&lt;p&gt;In this model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript changes data&lt;/li&gt;
&lt;li&gt;CSS handles presentation&lt;/li&gt;
&lt;li&gt;The browser manages propagation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The system becomes simpler because responsibilities become clearer.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why This Matters Beyond Performance
&lt;/h1&gt;

&lt;p&gt;The biggest advantage may not even be speed.&lt;/p&gt;

&lt;p&gt;It may be accessibility.&lt;/p&gt;

&lt;p&gt;Modern frontend development has become increasingly hostile to newcomers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;complex build chains&lt;/li&gt;
&lt;li&gt;framework churn&lt;/li&gt;
&lt;li&gt;hydration bugs&lt;/li&gt;
&lt;li&gt;SSR edge cases&lt;/li&gt;
&lt;li&gt;compiler-specific syntax&lt;/li&gt;
&lt;li&gt;dependency fatigue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Building simple interactive websites now often requires knowledge of infrastructure that didn’t even exist a few years ago.&lt;/p&gt;

&lt;p&gt;CSS reactive systems reduce that complexity dramatically because the application remains fundamentally HTML-first.&lt;/p&gt;

&lt;p&gt;The app &lt;em&gt;is&lt;/em&gt; the document.&lt;/p&gt;

&lt;p&gt;That makes the platform easier to reason about, easier to debug, and significantly easier to teach.&lt;/p&gt;




&lt;h1&gt;
  
  
  Returning to the Browser Instead of Escaping It
&lt;/h1&gt;

&lt;p&gt;For years, frontend engineering focused on abstracting developers away from the browser.&lt;/p&gt;

&lt;p&gt;But the browser itself kept evolving.&lt;/p&gt;

&lt;p&gt;Native CSS now supports features that previously required entire JavaScript ecosystems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scroll timelines&lt;/li&gt;
&lt;li&gt;container queries&lt;/li&gt;
&lt;li&gt;view transitions&lt;/li&gt;
&lt;li&gt;hardware compositing&lt;/li&gt;
&lt;li&gt;declarative animation pipelines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The platform is catching up to the abstractions.&lt;/p&gt;

&lt;p&gt;And in many cases, surpassing them.&lt;/p&gt;

&lt;p&gt;CSS reactive frameworks like State.js represent a larger philosophical shift:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Instead of rebuilding the browser in JavaScript, what if we simply embraced the browser as the runtime?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;The “No-JS” paradox feels impossible only because the industry spent years assuming that interactivity must flow through JavaScript rendering systems.&lt;/p&gt;

&lt;p&gt;But the browser was reactive long before modern frameworks arrived.&lt;/p&gt;

&lt;p&gt;State.js demonstrates that when state flows directly through CSS and the DOM becomes the source of truth, applications become simpler, faster, and dramatically more transparent.&lt;/p&gt;

&lt;p&gt;It’s not about abandoning modern web development.&lt;/p&gt;

&lt;p&gt;It’s about removing unnecessary layers between your data and the screen.&lt;/p&gt;

&lt;p&gt;And perhaps more importantly:&lt;/p&gt;

&lt;p&gt;It makes building for the web feel immediate, creative, and fun again.&lt;/p&gt;




&lt;h1&gt;
  
  
  Explore the Project
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/iDev-Games/State-JS" rel="noopener noreferrer"&gt;State.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/iDev-Games/Trig.js" rel="noopener noreferrer"&gt;Trig.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/iDev-Games/Motion-JS" rel="noopener noreferrer"&gt;Motion.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/iDev-Games/Keys-JS" rel="noopener noreferrer"&gt;Keys.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>html</category>
      <category>css</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I Built a Real-Time Simulation Game in a Single HTML File (Without React or Custom JavaScript)</title>
      <dc:creator>iDev-Games</dc:creator>
      <pubDate>Tue, 26 May 2026 20:39:03 +0000</pubDate>
      <link>https://dev.to/idevgames/i-built-a-real-time-simulation-game-in-a-single-html-file-without-react-or-custom-javascript-262p</link>
      <guid>https://dev.to/idevgames/i-built-a-real-time-simulation-game-in-a-single-html-file-without-react-or-custom-javascript-262p</guid>
      <description>&lt;p&gt;Modern frontend development has normalized an absurd amount of complexity.&lt;/p&gt;

&lt;p&gt;Want to build a real-time app or simulation game?&lt;/p&gt;

&lt;p&gt;Apparently you now need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React or Vue&lt;/li&gt;
&lt;li&gt;Virtual DOM rendering&lt;/li&gt;
&lt;li&gt;State management libraries&lt;/li&gt;
&lt;li&gt;Bundlers like Vite/Webpack&lt;/li&gt;
&lt;li&gt;Hydration pipelines&lt;/li&gt;
&lt;li&gt;Component trees&lt;/li&gt;
&lt;li&gt;Build steps&lt;/li&gt;
&lt;li&gt;Thousands of lines of JavaScript&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But what if you could build a fully autonomous real-time simulation game using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML&lt;/li&gt;
&lt;li&gt;CSS&lt;/li&gt;
&lt;li&gt;Declarative attributes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…and almost no custom JavaScript at all?&lt;/p&gt;

&lt;p&gt;That’s exactly what I did with &lt;strong&gt;Spore Colony&lt;/strong&gt;, a real-time autonomous simulation game powered entirely by &lt;strong&gt;State.js&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The entire application runs from a &lt;strong&gt;single HTML file&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;No React.&lt;br&gt;
No re-rendering.&lt;br&gt;
No framework overhead.&lt;br&gt;
No build tools.&lt;/p&gt;

&lt;p&gt;Just native browser technology pushed to its limits.&lt;/p&gt;


&lt;h2&gt;
  
  
  🚀 Live Demo
&lt;/h2&gt;

&lt;p&gt;Check out the live CodePen demo here:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/iDev-Games/embed/ByQwWgq?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;👉 &lt;em&gt;Spore Colony — Autonomous Simulation&lt;/em&gt;&lt;br&gt;
&lt;a href="https://codepen.io/iDev-Games/pen/ByQwWgq" rel="noopener noreferrer"&gt;Codepen URL&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the framework powering it:&lt;/p&gt;

&lt;p&gt;📦 GitHub: &lt;a href="https://github.com/iDev-Games/State-JS?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;State-JS by iDev-Games&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  The Big Idea: The DOM Is Already a Database
&lt;/h3&gt;

&lt;p&gt;Most frontend frameworks treat the DOM like a disposable rendering target.&lt;/p&gt;

&lt;p&gt;The actual application state lives somewhere else:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript objects&lt;/li&gt;
&lt;li&gt;stores&lt;/li&gt;
&lt;li&gt;reducers&lt;/li&gt;
&lt;li&gt;proxies&lt;/li&gt;
&lt;li&gt;signals&lt;/li&gt;
&lt;li&gt;virtual DOM trees&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The framework continuously syncs those structures back into the browser.&lt;/p&gt;

&lt;p&gt;But browsers already ship with a fully reactive document system:&lt;/p&gt;

&lt;p&gt;The DOM itself.&lt;/p&gt;

&lt;p&gt;State.js flips the model completely:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your HTML becomes the application state layer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of managing state in JavaScript, state lives directly on elements using native &lt;code&gt;data-*&lt;/code&gt; attributes.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"colony"&lt;/span&gt;
  &lt;span class="na"&gt;data-state&lt;/span&gt;
  &lt;span class="na"&gt;data-state-watch=&lt;/span&gt;&lt;span class="s"&gt;"spores,bio,mut,haz,cycle,nodes,boosted,collapsed"&lt;/span&gt;
  &lt;span class="na"&gt;data-state-var=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
  &lt;span class="na"&gt;data-state-persist=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
  &lt;span class="na"&gt;data-state-toggles=&lt;/span&gt;&lt;span class="s"&gt;"ticking,danger,mutating,thriving"&lt;/span&gt;

  &lt;span class="na"&gt;data-spores=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt;
  &lt;span class="na"&gt;data-spores-min=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
  &lt;span class="na"&gt;data-spores-max=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt;

  &lt;span class="na"&gt;data-bio=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
  &lt;span class="na"&gt;data-bio-min=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
  &lt;span class="na"&gt;data-bio-max=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;

  &lt;span class="na"&gt;data-mut=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
  &lt;span class="na"&gt;data-mut-min=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
  &lt;span class="na"&gt;data-mut-max=&lt;/span&gt;&lt;span class="s"&gt;"30"&lt;/span&gt;

  &lt;span class="na"&gt;data-haz=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
  &lt;span class="na"&gt;data-haz-min=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
  &lt;span class="na"&gt;data-haz-max=&lt;/span&gt;&lt;span class="s"&gt;"20"&lt;/span&gt;

  &lt;span class="na"&gt;data-cycle=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;

  &lt;span class="na"&gt;data-nodes=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;
  &lt;span class="na"&gt;data-nodes-min=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;
  &lt;span class="na"&gt;data-nodes-max=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt;

  &lt;span class="na"&gt;data-boosted=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
  &lt;span class="na"&gt;data-collapsed=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That single block becomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the game database&lt;/li&gt;
&lt;li&gt;the reactive state store&lt;/li&gt;
&lt;li&gt;the UI binding system&lt;/li&gt;
&lt;li&gt;the persistence layer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;State.js automatically maps those attributes into live CSS custom properties.&lt;/p&gt;

&lt;p&gt;Which means the browser itself becomes the rendering engine.&lt;/p&gt;




&lt;h3&gt;
  
  
  ⚡ Building Autonomous Game Loops Without &lt;code&gt;setInterval()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Traditional JavaScript games rely heavily on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;loops&lt;/li&gt;
&lt;li&gt;timers&lt;/li&gt;
&lt;li&gt;state mutation functions&lt;/li&gt;
&lt;li&gt;imperative event pipelines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;State.js turns all of that into declarative markup.&lt;/p&gt;

&lt;p&gt;Here’s an autonomous resource growth loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"t-grow"&lt;/span&gt;
  &lt;span class="na"&gt;data-state&lt;/span&gt;
  &lt;span class="na"&gt;data-state-trigger&lt;/span&gt;
  &lt;span class="na"&gt;data-state-bind=&lt;/span&gt;&lt;span class="s"&gt;"colony"&lt;/span&gt;
  &lt;span class="na"&gt;data-state-attr=&lt;/span&gt;&lt;span class="s"&gt;"spores"&lt;/span&gt;
  &lt;span class="na"&gt;data-state-increment=&lt;/span&gt;&lt;span class="s"&gt;"calc(var(--state-nodes))"&lt;/span&gt;
  &lt;span class="na"&gt;data-state-condition=&lt;/span&gt;&lt;span class="s"&gt;"spores &amp;lt; 95 and collapsed &amp;lt; 1"&lt;/span&gt;
  &lt;span class="na"&gt;data-state-interval=&lt;/span&gt;&lt;span class="s"&gt;"2000"&lt;/span&gt;
  &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:none"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That single hidden element:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;runs on an interval&lt;/li&gt;
&lt;li&gt;evaluates conditions&lt;/li&gt;
&lt;li&gt;updates state&lt;/li&gt;
&lt;li&gt;scales dynamically&lt;/li&gt;
&lt;li&gt;binds to another element&lt;/li&gt;
&lt;li&gt;triggers autonomously&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No manual timer code required.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧮 Dynamic Game Math Using Native CSS Variables
&lt;/h2&gt;

&lt;p&gt;Because State.js exposes state directly as CSS custom properties, you can use native browser math for game logic.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;data-state-attr="bio"
data-state-increment="calc(10 + var(--state-nodes) * 2)"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;infrastructure scaling&lt;/li&gt;
&lt;li&gt;economy balancing&lt;/li&gt;
&lt;li&gt;production pipelines&lt;/li&gt;
&lt;li&gt;progression systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…can all be expressed declaratively.&lt;/p&gt;

&lt;p&gt;Without custom calculation functions.&lt;/p&gt;

&lt;p&gt;Without reducers.&lt;/p&gt;

&lt;p&gt;Without giant state trees.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔗 DOM-Based Chain Reactions
&lt;/h2&gt;

&lt;p&gt;One of the most interesting parts of the project was replacing procedural reset logic with pure DOM chaining.&lt;/p&gt;

&lt;p&gt;Normally a game reset requires a giant JavaScript function.&lt;/p&gt;

&lt;p&gt;With State.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"t-r-spores"&lt;/span&gt;
  &lt;span class="na"&gt;data-state-attr=&lt;/span&gt;&lt;span class="s"&gt;"spores"&lt;/span&gt;
  &lt;span class="na"&gt;data-state-set=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt;
  &lt;span class="na"&gt;data-state-trigger-chain=&lt;/span&gt;&lt;span class="s"&gt;"t-r-bio"&lt;/span&gt;
  &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:none"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"t-r-bio"&lt;/span&gt;
  &lt;span class="na"&gt;data-state-attr=&lt;/span&gt;&lt;span class="s"&gt;"bio"&lt;/span&gt;
  &lt;span class="na"&gt;data-state-set=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
  &lt;span class="na"&gt;data-state-trigger-chain=&lt;/span&gt;&lt;span class="s"&gt;"t-r-mut"&lt;/span&gt;
  &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:none"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each state mutation triggers the next one like falling dominoes.&lt;/p&gt;

&lt;p&gt;The DOM itself becomes an event orchestration system.&lt;/p&gt;




&lt;h3&gt;
  
  
  🎨 Zero-JS Rendering With Pure CSS
&lt;/h3&gt;

&lt;p&gt;This is where the architecture gets really interesting.&lt;/p&gt;

&lt;p&gt;In React:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;State changes&lt;/li&gt;
&lt;li&gt;Components re-render&lt;/li&gt;
&lt;li&gt;Diffing happens&lt;/li&gt;
&lt;li&gt;The DOM updates&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With State.js:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;State attributes update&lt;/li&gt;
&lt;li&gt;CSS variables change&lt;/li&gt;
&lt;li&gt;The browser handles rendering natively&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No component lifecycle.&lt;/p&gt;

&lt;p&gt;No reconciliation.&lt;/p&gt;

&lt;p&gt;No virtual DOM.&lt;/p&gt;




&lt;h2&gt;
  
  
  Example: Dynamic Resource Bars
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.bf-s&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="m"&gt;90deg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spore3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spore&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--state-spores-percent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The UI updates automatically because the CSS variable itself changes.&lt;/p&gt;

&lt;p&gt;No rendering glue code exists.&lt;/p&gt;




&lt;h2&gt;
  
  
  Example: Reactive Petri Dish Simulation
&lt;/h2&gt;

&lt;p&gt;One of my favorite systems was the colony density visualization.&lt;/p&gt;

&lt;p&gt;Instead of looping through cells in JavaScript, I used native CSS selectors tied directly to state attributes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#colony&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;data-state-spores&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"40"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="nc"&gt;.cell&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;-n&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="err"&gt;22&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spore2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;57&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;106&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the spore count changes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the DOM attribute updates&lt;/li&gt;
&lt;li&gt;the selector matches instantly&lt;/li&gt;
&lt;li&gt;the browser paints the new cells&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The browser’s internal rendering engine does all the work.&lt;/p&gt;

&lt;p&gt;No JavaScript loops required.&lt;/p&gt;




&lt;h2&gt;
  
  
  📉 Why This Approach Is Surprisingly Fast
&lt;/h2&gt;

&lt;p&gt;Modern frameworks often spend enormous resources managing abstraction layers.&lt;/p&gt;

&lt;p&gt;State.js removes most of them.&lt;/p&gt;

&lt;p&gt;Benefits include:&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ No Virtual DOM
&lt;/h2&gt;

&lt;p&gt;No diffing.&lt;br&gt;
No reconciliation.&lt;br&gt;
No component tree overhead.&lt;/p&gt;


&lt;h2&gt;
  
  
  ✅ Hardware-Accelerated CSS Rendering
&lt;/h2&gt;

&lt;p&gt;Updates route directly into CSS variables, allowing browsers to optimize transitions on the compositor thread.&lt;/p&gt;


&lt;h2&gt;
  
  
  ✅ Tiny Runtime Footprint
&lt;/h2&gt;

&lt;p&gt;The entire game architecture remains extremely lightweight.&lt;/p&gt;

&lt;p&gt;No framework bundle bloat.&lt;/p&gt;


&lt;h2&gt;
  
  
  ✅ Single File Portability
&lt;/h2&gt;

&lt;p&gt;The game can run locally by simply opening:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No servers required.&lt;/p&gt;

&lt;p&gt;No npm install.&lt;/p&gt;

&lt;p&gt;No bundling pipeline.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 The Bigger Philosophy
&lt;/h2&gt;

&lt;p&gt;This project started as an experiment.&lt;/p&gt;

&lt;p&gt;But it evolved into something much larger:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What if modern frontend development has massively overcomplicated interactivity?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Browsers already provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reactive styling&lt;/li&gt;
&lt;li&gt;event systems&lt;/li&gt;
&lt;li&gt;rendering engines&lt;/li&gt;
&lt;li&gt;selectors&lt;/li&gt;
&lt;li&gt;animations&lt;/li&gt;
&lt;li&gt;variables&lt;/li&gt;
&lt;li&gt;stateful attributes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Frameworks often rebuild systems browsers already solved years ago.&lt;/p&gt;

&lt;p&gt;State.js explores the opposite direction:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fewer abstractions&lt;/li&gt;
&lt;li&gt;more native browser capabilities&lt;/li&gt;
&lt;li&gt;declarative architecture&lt;/li&gt;
&lt;li&gt;DOM-first state management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s the same philosophy that inspired my earlier project, Trig.js, which reimagined scroll animations using HTML attributes and CSS instead of heavy JavaScript animation frameworks.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔮 Could HTML Become Reactive Again?
&lt;/h2&gt;

&lt;p&gt;There’s something powerful about opening a single HTML file and immediately understanding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the application state&lt;/li&gt;
&lt;li&gt;the game rules&lt;/li&gt;
&lt;li&gt;the rendering logic&lt;/li&gt;
&lt;li&gt;the UI bindings&lt;/li&gt;
&lt;li&gt;the behavior system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All in one place.&lt;/p&gt;

&lt;p&gt;No build process required.&lt;/p&gt;

&lt;p&gt;No hidden architecture.&lt;/p&gt;

&lt;p&gt;No framework magic.&lt;/p&gt;

&lt;p&gt;Just the web platform itself.&lt;/p&gt;




&lt;h2&gt;
  
  
  📦 Project Links
&lt;/h2&gt;

&lt;h2&gt;
  
  
  State.js
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/iDev-Games/State-JS?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;State-JS GitHub Repository&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;👉 &lt;em&gt;Spore Colony — Autonomous Simulation&lt;/em&gt;&lt;br&gt;
&lt;a href="https://codepen.io/iDev-Games/pen/ByQwWgq" rel="noopener noreferrer"&gt;Codepen URL&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  💬 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;I genuinely think we’re entering a phase where developers are re-evaluating how much tooling is actually necessary.&lt;/p&gt;

&lt;p&gt;Not every application needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a virtual DOM&lt;/li&gt;
&lt;li&gt;hydration&lt;/li&gt;
&lt;li&gt;client/server rendering pipelines&lt;/li&gt;
&lt;li&gt;giant dependency trees&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes the fastest solution is simply leaning harder into the browser itself.&lt;/p&gt;

&lt;p&gt;Would you build apps this way?&lt;/p&gt;

&lt;p&gt;Could declarative HTML state management become viable for indie games, dashboards, or interactive tools?&lt;/p&gt;

&lt;p&gt;Curious to hear what other developers think.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to Embed HTML5 Games on Your Website (Fast, Ad-Free &amp; No Lag)</title>
      <dc:creator>iDev-Games</dc:creator>
      <pubDate>Wed, 25 Mar 2026 12:19:28 +0000</pubDate>
      <link>https://dev.to/idevgames/how-to-embed-html5-games-on-your-website-fast-ad-free-no-lag-3f1d</link>
      <guid>https://dev.to/idevgames/how-to-embed-html5-games-on-your-website-fast-ad-free-no-lag-3f1d</guid>
      <description>&lt;p&gt;Learn how to embed HTML5 games on your site in 2026 without slow iframes, ads, or complicated SDKs — including a simple WordPress plugin for instant results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Embedding HTML5 games on your website sounds simple — copy-paste an iframe, right?&lt;/p&gt;

&lt;p&gt;In reality, &lt;strong&gt;performance issues, ad networks, and bloated plugins&lt;/strong&gt; often ruin the player experience and slow down your site.&lt;/p&gt;

&lt;p&gt;In this guide, you’ll learn how to &lt;strong&gt;embed games properly in 2026&lt;/strong&gt;, giving your players a fast, smooth, and ad-free experience — while also keeping your content fully under your control.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Common embedding mistakes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Iframes with third-party ads&lt;/strong&gt; → slow load, poor UX&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heavy WordPress plugins&lt;/strong&gt; → bloated, outdated, hard to maintain&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom SDKs or JS wrappers&lt;/strong&gt; → unnecessarily complex&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These create friction for players, reducing engagement and repeat visits.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: The simple solution — iDev.Games
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;iDev.Games&lt;/strong&gt; solves all these problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Instant embed&lt;/strong&gt; — iframe-ready or direct link&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Ad-free gameplay&lt;/strong&gt; — no interruptions for your users&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;No SDKs required&lt;/strong&gt; — works on any site&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;WordPress plugin available&lt;/strong&gt; — drag-and-drop embed&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Privacy-conscious&lt;/strong&gt; — players keep control of their data&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Global CDN&lt;/strong&gt; — Game files are cached on global servers&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Built by a single indie developer, iDev.Games makes embedding &lt;strong&gt;easy, reliable, and future-proof&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 3: Embed your game manually
&lt;/h2&gt;

&lt;p&gt;You can embed games anywhere with a single iframe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- iDev.Games Responsive Embed Code for Bitcoin Wallet Simulator --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position: relative;height: 0;overflow: hidden;padding-bottom: 56.25%;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"embededGame"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://idev.games/embed/bitcoin-wallet-simulator"&lt;/span&gt; &lt;span class="na"&gt;scrolling=&lt;/span&gt;&lt;span class="s"&gt;"no"&lt;/span&gt; &lt;span class="na"&gt;seamless=&lt;/span&gt;&lt;span class="s"&gt;"seamless"&lt;/span&gt; &lt;span class="na"&gt;frameBorder=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position: absolute;top:0;left: 0;width: 100%;height: 100%;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Browser not compatible.&lt;span class="nt"&gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- End Embed Code --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Fully responsive&lt;/li&gt;
&lt;li&gt;Works in all modern browsers&lt;/li&gt;
&lt;li&gt;No extra scripts or SDKs&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;This keeps your page fast and your players happy.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 4: Embed using WordPress plugin
&lt;/h2&gt;

&lt;p&gt;If you run a WordPress site, iDev.Games offers a &lt;strong&gt;free plugin&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install the plugin from &lt;a href="https://idev.games/wordpress-game-plugin" rel="noopener noreferrer"&gt;iDev Games WordPress Plugin&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Search for your uploaded game&lt;/li&gt;
&lt;li&gt;Drag and drop into any post or page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No coding required. It’s &lt;strong&gt;simple, fast, and ad-free&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Make embedded games more discoverable
&lt;/h2&gt;

&lt;p&gt;Embedding alone isn’t enough. To get players:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Link your embedded game to your &lt;strong&gt;iDev.Games profile&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Cross-link with relevant categories&lt;/li&gt;
&lt;li&gt;Encourage players to explore other games via curated pages like &lt;a href="https://idev.games/games-to-play-at-work" rel="noopener noreferrer"&gt;Games to Play at Work&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;The smoother the experience, the more likely players will return — which benefits both you and your embedded content.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 6: Optional — reward your players
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduce &lt;strong&gt;iDev Token rewards&lt;/strong&gt; (optional)&lt;/li&gt;
&lt;li&gt;Keep players engaged and coming back&lt;/li&gt;
&lt;li&gt;Works naturally with embedded games — no SDK, no ads&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Embedding HTML5 games doesn’t have to be painful or slow. With iDev.Games:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instant iframe or plugin embed&lt;/li&gt;
&lt;li&gt;Ad-free and responsive&lt;/li&gt;
&lt;li&gt;No SDK or complex setup&lt;/li&gt;
&lt;li&gt;Optional player rewards and monetisation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start embedding your games the &lt;strong&gt;right way in 2026&lt;/strong&gt; and give your players a fast, smooth, and engaging experience.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>javascript</category>
      <category>unity3d</category>
      <category>godot</category>
    </item>
    <item>
      <title>How to Upload HTML5 Games and Actually Get Players (2026 Guide)</title>
      <dc:creator>iDev-Games</dc:creator>
      <pubDate>Wed, 25 Mar 2026 12:07:30 +0000</pubDate>
      <link>https://dev.to/idevgames/how-to-upload-html5-games-and-actually-get-players-2026-guide-31p7</link>
      <guid>https://dev.to/idevgames/how-to-upload-html5-games-and-actually-get-players-2026-guide-31p7</guid>
      <description>&lt;p&gt;Learn the fastest way to upload your HTML5 game, embed it, and start getting real players — no servers, no ads, no SDKs. Built for indie developers in 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you’ve ever tried to &lt;strong&gt;upload an HTML5 game&lt;/strong&gt;, you know it’s not as simple as dragging a file to a server. Between hosting headaches, embedding issues, and getting actual players, it can feel impossible.&lt;/p&gt;

&lt;p&gt;In this guide, we’ll show you how &lt;strong&gt;to publish your browser game in 2026&lt;/strong&gt; in a way that actually reaches players — without servers, SDKs, or ad networks — using a &lt;strong&gt;privacy-conscious, developer-first platform built for the open web&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Why traditional upload methods fail
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Generic hosting&lt;/strong&gt; (like FTP or free file hosts) → No analytics, no player engagement&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CMS plugins&lt;/strong&gt; (WordPress arcade plugins) → Slow, bloated, hard to maintain&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-built backends&lt;/strong&gt; → Overkill for a single game or small portfolio&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These methods often lead to frustration and &lt;strong&gt;no real players discovering your game&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: The modern solution — iDev.Games
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;iDev.Games&lt;/strong&gt; is a platform built by a single indie developer that solves these problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;No backend required&lt;/strong&gt; — upload, embed, and go live&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;0% commission payments&lt;/strong&gt; — direct to your PayPal, no middleman&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Ad-free gameplay&lt;/strong&gt; — better player experience&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Privacy-conscious&lt;/strong&gt; — player data is safe&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Developer and player oriented&lt;/strong&gt; — designed for real indie games&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Think of it as &lt;strong&gt;the future of the open web for browser games&lt;/strong&gt;, where developers maintain control and players get seamless experiences.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 3: How to upload your HTML5 game
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Sign up for an iDev.Games account&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upload your ZIP file&lt;/strong&gt; containing your game assets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set metadata&lt;/strong&gt;: title, description, thumbnail&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Select your monetisation&lt;/strong&gt;: optional direct PayPal payments&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Publish&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your game is now live. You’ll also get a &lt;strong&gt;link to embed&lt;/strong&gt; on your own website, or use the &lt;strong&gt;WordPress plugin&lt;/strong&gt; to instantly place your game without coding: &lt;a href="https://idev.games/wordpress-game-plugin" rel="noopener noreferrer"&gt;iDev Games WordPress Plugin&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: How to get players (this is key)
&lt;/h2&gt;

&lt;p&gt;Uploading alone isn’t enough — you need &lt;strong&gt;real discovery&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Share the &lt;strong&gt;direct link&lt;/strong&gt; to your game&lt;/li&gt;
&lt;li&gt;Use the &lt;strong&gt;Games for Work&lt;/strong&gt; page as inspiration for where players are looking: &lt;a href="https://idev.games/games-to-play-at-work" rel="noopener noreferrer"&gt;Games to Play at Work&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Add your game to &lt;strong&gt;iDev.Games categories&lt;/strong&gt; for search optimisation&lt;/li&gt;
&lt;li&gt;Promote on social / community channels for initial traction&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Players find your game faster if the experience is &lt;strong&gt;smooth, ad-free, and instantly playable&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 5: Embed your game on your own website
&lt;/h2&gt;

&lt;p&gt;With iDev.Games, embedding is simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- iDev.Games Responsive Embed Code for Bitcoin Wallet Simulator --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position: relative;height: 0;overflow: hidden;padding-bottom: 56.25%;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"embededGame"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://idev.games/embed/bitcoin-wallet-simulator"&lt;/span&gt; &lt;span class="na"&gt;scrolling=&lt;/span&gt;&lt;span class="s"&gt;"no"&lt;/span&gt; &lt;span class="na"&gt;seamless=&lt;/span&gt;&lt;span class="s"&gt;"seamless"&lt;/span&gt; &lt;span class="na"&gt;frameBorder=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position: absolute;top:0;left: 0;width: 100%;height: 100%;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Browser not compatible.&lt;span class="nt"&gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- End Embed Code --&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above is an example of one of the games on the platform. These codes are provided for every game.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No SDK&lt;/li&gt;
&lt;li&gt;No ad code&lt;/li&gt;
&lt;li&gt;Fully responsive&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Reclaim control over your content while keeping the player experience seamless.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 6: Optional — reward players with iDev Token
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;iDev.Games now allows &lt;strong&gt;free crypto rewards for players&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Encourage repeat plays and engagement without forcing purchases&lt;/li&gt;
&lt;li&gt;Perfect for building a small but loyal audience&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Uploading HTML5 games doesn’t have to be complicated. With &lt;strong&gt;iDev.Games&lt;/strong&gt;, you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple publishing&lt;/li&gt;
&lt;li&gt;Fast player discovery&lt;/li&gt;
&lt;li&gt;Ad-free gameplay&lt;/li&gt;
&lt;li&gt;Optional monetisation with &lt;strong&gt;0% fees&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Privacy and player trust&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stop struggling with messy hosting or bloated plugins — &lt;strong&gt;upload, embed, and grow your audience&lt;/strong&gt; the right way in 2026.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>gamedev</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Stop Joining Game Jams and Start Hosting Them: A 2026 Guide to Building Your Own Dev Community</title>
      <dc:creator>iDev-Games</dc:creator>
      <pubDate>Tue, 17 Mar 2026 12:34:38 +0000</pubDate>
      <link>https://dev.to/idevgames/stop-joining-game-jams-and-start-hosting-them-a-2026-guide-to-building-your-own-dev-community-19f4</link>
      <guid>https://dev.to/idevgames/stop-joining-game-jams-and-start-hosting-them-a-2026-guide-to-building-your-own-dev-community-19f4</guid>
      <description>&lt;p&gt;That is a fantastic "hidden gem" feature to highlight. Most developers think they have to use itch.io or a dedicated jam site to run a competition, which often means they have to manually manage submissions or deal with external hosting.&lt;/p&gt;

&lt;p&gt;By showing them they can host a jam directly where the games are played, you’re offering a &lt;strong&gt;closed-loop ecosystem&lt;/strong&gt;: They host the jam, the games get instant traffic, and the developers get immediate feedback from players—not just other jammers.&lt;/p&gt;




&lt;h3&gt;
  
  
  DEV.to Article: The "Community Builder" Angle
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Target Tags:&lt;/strong&gt; #gamedev #indiedev #community #gamejam&lt;/p&gt;

&lt;h2&gt;
  
  
  Title: Stop Joining Game Jams and Start Hosting Them: A 2026 Guide to Building Your Own Dev Community
&lt;/h2&gt;

&lt;p&gt;If you’re an indie dev or a community leader, you’ve probably joined a dozen game jams. You know the drill: 48 hours of caffeine, a half-finished prototype, and the hope that a few people might play your game before it disappears into the "Submissions" abyss.&lt;/p&gt;

&lt;p&gt;But in 2026, the real power move isn't just &lt;em&gt;entering&lt;/em&gt; a jam—it's &lt;strong&gt;hosting&lt;/strong&gt; one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Host Your Own Jam?
&lt;/h3&gt;

&lt;p&gt;Hosting a jam positions you as a "Hub." Instead of fighting for attention in a massive global event, you create a focused space for a specific theme, mechanic, or niche.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Networking:&lt;/strong&gt; You become the point of contact for dozens of talented creators.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content:&lt;/strong&gt; Every game submitted to your jam is a piece of content you can showcase, stream, or review.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Platform Growth:&lt;/strong&gt; If you have a site, a Discord, or a YouTube channel, a jam is the ultimate "Engagement Gravity" tool.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The "Frictionless" Setup
&lt;/h3&gt;

&lt;p&gt;One of the biggest hurdles to hosting is the technical setup. You usually have to worry about submission forms, file hosting, and voting systems.&lt;/p&gt;

&lt;p&gt;I’ve been utilizing the &lt;strong&gt;iDev.Games Jam Tool&lt;/strong&gt; because it removes the "webmaster" headache. Once you’re logged in, you can &lt;a href="https://idev.games/jams" rel="noopener noreferrer"&gt;create a jam in about 60 seconds&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The workflow is simple:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Set the Theme:&lt;/strong&gt; Give them something to chew on (e.g., "One Button Wonders" or "Retro-Future").&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Define the Timeline:&lt;/strong&gt; 48 hours is the classic, but 7-day jams are becoming more popular in 2026 to avoid "crunch" culture.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated Submissions:&lt;/strong&gt; Developers upload directly to the portal. No broken ZIP files, no external hosting—the game is playable in the browser the second they hit "Submit."&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  3 Tips for a Successful First Jam
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Keep the Theme Open:&lt;/strong&gt; Don't be too restrictive. You want to see &lt;em&gt;variety&lt;/em&gt;, not 50 versions of the exact same game.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Focus on the Play:&lt;/strong&gt; Encourage jammers to include a "Quick Play" version of their game. In 2026, if a game takes 3 minutes to load, people will skip it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Engage with Every Entry:&lt;/strong&gt; As the host, your #1 job is to leave a comment on every submission. That 10 seconds of your time is why developers will come back for your &lt;em&gt;next&lt;/em&gt; jam.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Want to know more about hosting your games on iDev.Games? Take a look at this article: &lt;a href="https://dev.to/idevgames/how-to-upload-host-and-embed-an-html5-game-complete-guide-for-indie-devs-1m56"&gt;How to Upload, Host, and Embed an HTML5 Game (Complete Guide for Indie Devs)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>community</category>
      <category>gamedev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Why I’m Done with WordPress Arcade Plugins in 2026 (And the Lightweight Way I Host Games Instead)</title>
      <dc:creator>iDev-Games</dc:creator>
      <pubDate>Tue, 17 Mar 2026 10:33:58 +0000</pubDate>
      <link>https://dev.to/idevgames/why-im-done-with-wordpress-arcade-plugins-in-2026-and-the-lightweight-way-i-host-games-instead-5bng</link>
      <guid>https://dev.to/idevgames/why-im-done-with-wordpress-arcade-plugins-in-2026-and-the-lightweight-way-i-host-games-instead-5bng</guid>
      <description>&lt;p&gt;If you’ve been in the WordPress ecosystem as long as I have, you remember the "Gold Rush" of arcade sites. Back then, plugins like MyArcadePlugin were the undisputed kings. They promised to turn your site into a gaming powerhouse with one click.&lt;/p&gt;

&lt;p&gt;But it’s 2026. The web has changed. &lt;strong&gt;Core Web Vitals&lt;/strong&gt; are no longer a "nice to have"—they are the primary gatekeeper for your Google rankings.&lt;/p&gt;

&lt;p&gt;If you are still using 2015-era architecture to host games on WordPress, you aren't just slowing down your site; you’re killing your SEO. Here is why I’ve pivoted away from traditional "Arcade Plugins" and how I’m building lightweight, high-engagement game portals today.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: The "Plugin Bloat" Death Spiral
&lt;/h2&gt;

&lt;p&gt;Traditional arcade plugins were built for a different era. They rely on heavy database queries, local file storage that eats up your disk space, and outdated PHP hooks that often clash with modern themes like Blockbase or Full Site Editing (FSE).&lt;/p&gt;

&lt;p&gt;When you install a legacy arcade suite, you're usually adding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JS/CSS Overhead:&lt;/strong&gt; Loading heavy scripts on every single page, even when no game is present.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Higher Running Costs:&lt;/strong&gt; Hosting all the game files can cost a lot more to host.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The 2026 Solution: Headless Game Hosting
&lt;/h2&gt;

&lt;p&gt;Instead of making WordPress do the heavy lifting of hosting, processing, and serving games, I’ve moved to a &lt;strong&gt;Headless approach.&lt;/strong&gt; By using &lt;a href="https://idev.games" rel="noopener noreferrer"&gt;iDev.Games&lt;/a&gt; as a backend, I treat my WordPress site as a clean, fast front-end. The games are served via a high-performance CDN, and the "heavy" lifting (leaderboards, cloud saves, and multiplayer infrastructure) happens off-server.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Benefits:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Perfect Core Web Vitals:&lt;/strong&gt; Since the games are embedded via optimized iframes, they don't block the main thread. Your LCP (Largest Contentful Paint) stays green.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Less Storage Costs:&lt;/strong&gt; You don’t need a 50GB hosting plan to house thousands of HTML5 games. You just pull the content you need (images, description, title and embed code).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Always Updated:&lt;/strong&gt; When a developer updates their game on iDev.Games, it automatically updates on your site. No more broken ZIP files or dead links.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How to Set It Up (No Plugin Required)
&lt;/h2&gt;

&lt;p&gt;You don't actually &lt;em&gt;need&lt;/em&gt; a massive plugin to create a professional arcade. You can do it with standard WordPress blocks.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The "Clean Embed" Method
&lt;/h3&gt;

&lt;p&gt;Every game on the iDev.Games platform provides a clean embed code. You can simply use the &lt;strong&gt;Custom HTML Block&lt;/strong&gt; to drop a game into any post or page.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pro Tip:&lt;/strong&gt; Set your iframe to &lt;code&gt;loading="lazy"&lt;/code&gt; to ensure it doesn't even touch your page speed until the user scrolls to it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. The "Modern Arcade" Plugin
&lt;/h3&gt;

&lt;p&gt;If you &lt;em&gt;do&lt;/em&gt; want a more automated approach, there is a lightweight &lt;a href="https://idev.games/wordpress-game-plugin" rel="noopener noreferrer"&gt;iDev.Games WordPress Plugin&lt;/a&gt;. Unlike the legacy "all-in-one" suites, this acts as a bridge. It pulls the data you want without the file bloat.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;In 2026, user experience is about speed and friction-less play. If your "Arcade" takes 5 seconds to load because of plugin overhead, your visitors are already gone.&lt;/p&gt;

&lt;p&gt;By offloading the game hosting to a dedicated, developer-first platform, you keep your WordPress site lean, your SEO healthy, and your players happy.&lt;/p&gt;

&lt;p&gt;If you're interested in why developers are moving to iDev.Games to release and maintain their games. Check out this post: &lt;strong&gt;&lt;a href="https://medium.com/@admin_75463/the-data-doesnt-lie-why-the-niche-web-game-platform-is-actually-the-highest-per-game-value-in-431f0b85a942" rel="noopener noreferrer"&gt;The Data Doesn’t Lie: Why the “Niche” Web Game Platform is Actually the Highest Per-Game Value in 2026&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>seo</category>
    </item>
  </channel>
</rss>
