State Management in HTML with Grains.js

I've built Grains.js. Grains.js is a lightweight framework that brings reactivity and state management to vanilla HTML, similar to Alpine.js and HTMX, but with built-in state tracking. Grains.js uses directives as a declarative approach and pure functions for state changers. Getting Started First, you need to include Grains.js into your page: To define state in Grains.js, you use the g-state directive. This automatically initializes a reactive state that can be referenced throughout your HTML. Example: Counter with Reactive State Count: Increment Decrement How It Works Define state: The g-state="counter" initializes a state variable called counter. This creates a global variable counter. If you inspect it in console as window.counter you'll see its value as Proxy(Object) {count: 0}. Whereas window.counter.count is equal to zero. Set initial value: The g-init='{"count": 0}' assigns an initial value. This can also be like g-init="myCount", which is referenced to a global variable window.myCount that you have to create. Bind state to elements: The updates dynamically when counter changes. Modify state with events: The g-on:click="increment" updates the state on button click. Define State Changers State changes are immutable and to dispatch the change we only create global pure functions. In our case increment is a global pure function, which you can inspect as window.increment. To dispatch the change we use .set method and send the new state object as an argument: function increment(ctx) { ctx.set({ count: ctx.get("count") + 1 }); } function decrement(ctx) { ctx.set({ count: ctx.get("count") - 1 }); } Take a look at minimal example to get acquainted: https://mk0y.github.io/grains.js/examples/minimal.html. All examples can be found in the repo: https://github.com/mk0y/grains.js/tree/main/examples. Why Use Grains.js? ✅ Lightweight & Fast ✅ Declarative State Management ✅ Zero Build Step ✅ Reactive Without Virtual DOM With Grains.js, managing state in HTML is intuitive and powerful, making it a great alternative for small, interactive UIs without the overhead of larger frameworks.

Apr 6, 2025 - 11:24
 0
State Management in HTML with Grains.js

I've built Grains.js. Grains.js is a lightweight framework that brings reactivity and state management to vanilla HTML, similar to Alpine.js and HTMX, but with built-in state tracking. Grains.js uses directives as a declarative approach and pure functions for state changers.

Getting Started

First, you need to include Grains.js into your page:


To define state in Grains.js, you use the g-state directive. This automatically initializes a reactive state that can be referenced throughout your HTML.

Example: Counter with Reactive State

 g-state="counter" g-init='{"count": 0}'>
  

Count: g-text="count"> g-on:click="increment">Increment g-on:click="decrement">Decrement

How It Works

  1. Define state: The g-state="counter" initializes a state variable called counter. This creates a global variable counter. If you inspect it in console as window.counter you'll see its value as Proxy(Object) {count: 0}. Whereas window.counter.count is equal to zero.

  2. Set initial value: The g-init='{"count": 0}' assigns an initial value. This can also be like g-init="myCount", which is referenced to a global variable window.myCount that you have to create.

  3. Bind state to elements: The updates dynamically when counter changes.

  4. Modify state with events: The g-on:click="increment" updates the state on button click.

Define State Changers

State changes are immutable and to dispatch the change we only create global pure functions. In our case increment is a global pure function, which you can inspect as window.increment.

To dispatch the change we use .set method and send the new state object as an argument:


Take a look at minimal example to get acquainted: https://mk0y.github.io/grains.js/examples/minimal.html.

All examples can be found in the repo: https://github.com/mk0y/grains.js/tree/main/examples.

Why Use Grains.js?

✅ Lightweight & Fast
✅ Declarative State Management
✅ Zero Build Step
✅ Reactive Without Virtual DOM

With Grains.js, managing state in HTML is intuitive and powerful, making it a great alternative for small, interactive UIs without the overhead of larger frameworks.