npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

stimulus-value-bindings

v0.1.0

Published

One-way reactive DOM bindings for Stimulus JS

Readme

stimulus-value-bindings 🪢

Reactive DOM value bindings for Stimulus JS.

NPM Version CI

Overview

stimulus-value-bindings allows DOM element attribute values to be reactively bound to Stimulus controller values so that the DOM attributes are automatically updated when their bound value property changes.

Bindings are:

  • reactive - every time a value is changed any bound attributes (or text contents) in the DOM are automatically (and transparently) updated to reflect the changes.
  • one-way - the flow of updates is always from the controller to the DOM. Direct manipulation to bound attributes in the DOM will not result in the controller values being updated.

stimulus-value-bindings can help you drastically reduce the amount of boring something-has-changed-and-now-the-DOM-needs-updating code in your Stimulus JS controllers.

[!WARNING] This documentation is a work-in-progress! Please open an issue if you are having problems.

Simple counter example

The example below is a simple 'counter' example that should help to demonstrate how reactive value bindings work.

▶️ View this example running in JSBin

// counter-controller.js
import { Controller } from "@hotwired/stimulus";
import { useValueBindings } from "stimulus-value-bindings";

export default class extends Controller {
  static values = {
    count: Number
  }

  connect(){
    useValueBindings(this);
  }

  increment(){
    this.countValue++;
  }

  decrement(){
    this.countValue--;
  }
}
<div data-controller="counter">
  <span id="count" data-counter-bind-text="countValue">0</span>

  <button data-action="counter#increment">+</button>
  <button data-action="counter#decrement">-</button>
</div>

When the + or - buttons are clicked the span#count element text content will be automatically be updated to reflect the current value of the count controller value. The counter display is kept in sync with the count value without needing to manually update the DOM after each change.

Installation

Add the stimulus-value-bindings package to your package.json:

Using NPM:

npm i stimulus-value-bindings --save

Using Yarn:

yarn add stimulus-value-bindings

Usage

The stimulus-value-bindings package exports a useValueBinding function that can be used to add reactive value binding functionality to controllers.

import { Controller } from "@hotwired/stimulus";
import { useValueBindings } from "stimulus-value-bindings";

export default class extends Controller {
  connect(){
    useValueBindings(this);
  }
}

Alternatively, the package also exports a 'ready to go' ValueBindingsController base controller if you prefer to extend rather than compose your classes:

import { ValueBindingsController } from "stimulus-value-bindings";

export default class extends ValueBindingsController {
  // ...
}

You can then delare controller values in the usual way, and bind DOM element attribute values and content to them using binding data attributes.

// read-more-controller.js
import { Controller } from "@hotwired/stimulus";
import { useValueBindings } from "stimulus-value-bindings";

export default class extends Controller {
  static values = {
    showMore: Boolean,
    buttonText: String
  }

  connect(){
    useValueBindings(this);
  }

  toggle(){
    this.openValue = !this.openValue;
    this.buttonTextValue = this.openValue ? "read less" : "read more";
  }
}
<div data-controller="read-more">
  <p>This is the summary content.</p>

  <button data-action="read-more#toggle" data-read-more-bind-text="buttonTextValue">read more</button>

  <p data-read-more-bind-hidden="!showMore" data-read-more-bind-aria-expanded="showMore" hidden>
    This is the additional content.
  </p>
</div>

In the example above, clicking the read more button will toggle the hidden attribute on the 'additional content' div to hide or show it. The button text will additonally be updated to read more or read less according to whether the additional content is currently hidden or shown respectively.

Adding bindings to elements

Bindings are declared on DOM elements using data attributes with the following format:

data-[identifier]-bind-[bindingType]="[valueName]"
  • [identifier]: The identifier of the target controller
  • [bindingType]: See below for the types of bindings available.
  • [valueName] The name of the value getter property to bind to.

Attribute bindings

The values of DOM element attributes can be bound to controller values using attribute bindings.

data-[identifier]-bind-[attribute-name]="[valueName]"

For example:

// defined in example-controller.js
static values = {
  progress: 0
}
<div data-controller="example">
  <h4>Uploading...</h4> 
  <progress data-example-bind-value="progressValue" max="100"></progress>
</div>

Boolean attributes

Boolean attributes will be added or removed according to the truthiness of the value they are bound to.

// defined in example-controller.js
static values = {
  hidden: Boolean,
}
<div data-controller="example">
  <div data-example-bind-hidden="hiddenValue">some content</div> 
</div>
  • When hiddenValue is true, the hidden attribute will be added to the bound element.
  • When hiddenValue is false, the hidden attribute will be removed from the element.

Element textContent binding

The textContent of elements can be bound to controller values using text bindings.

data-[identifier]-bind-text="[valueName]"

For example:

// defined in example-controller.js
static values = {
  count: Number
}
<div data-controller="example">
  <span data-example-bind-text="countValue">0</span>
</div>

Element bindings

Elements can be bound to Object-type values. An attribute or content binding will be created for each of the object's properties.

data-[identifier]-bind="[valueName]"

For example:

// defined in example-controller.js
static values = {
  input: {
    type: Object,
    default: {
      value: "default value",
      disabled: true
    }
  }
}
<div data-controller="example">
  <input data-example-bind="inputValue">
  <!-- renders: <input disabled="disabled" value="default value"> -->
</div>

Credits

stimulus-value-bindings is inspired by (and borrows code from!) the x-bind functionality in Alpine JS.

License

stimulus-value-bindings is available as open source under the terms of the MIT License.