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-bind

v0.9.0

Published

Enable simple data binding for stimulus framework

Readme

Use Stimulusjs with simple, one-way data binding to reduce boilerplate code.

It is just a 3k file when gzipped.

Usage

Include in your project:

yarn add stimulus-bind jsep stimulus
# or
npm i stimulus-bind jsep stimulus --save

Or use the stimulus.umd.js directly (which can expose a StimulusBind in global).

Template

<div data-controller="foo_controller">
  <label>
    My Name is
    <input type="text" data-action="input->foo_controller#nameChanged" data-target="my_name_input">
  </label>
  <div style="color:blue;" data-target="my_name_greet"/>
  <div style="color:red;" data-target="my_name_error">name is empty</div>
</div>

The use of data-controller, data-action and data-target is the same as in stimulus guide.

The JS is a bit different:

import StimulusBind from 'stimulus-bind'

class MyController extends StimulusBind {
  nameChanged() {
    this.myName = this.ref('my_name_input').value
  }
}

StimulusBind.register('foo_controller', MyController, {
  my_name_greet: {text: '"Hello, " + myName', if: 'myName'},
  my_name_error: {if: '!myName'}
})
  • Inherit the controller from StimulusBind instead of stimulus.Controller.
  • Do not set the targets field in controller, instead, set bindings when registering.
  • register under StimulusBind, a global app will be created when needed.
  • ref(targetName) returns the first target in or not in DOM (including the ones hidden by if binders).
  • refs(targetname) returns all targets, including the ones detached by if binders.

The binding data is in the format of:

{
    {targetName}: {{binder1}: {bindValueExpression1}, {binder2}: {bindValueExpression2}}
}

All bindings are one-way binding.

When the dependent data changed, targets with binders will react the update at once.

Expressions must a string of simple js expression that jsep can parse. In the expression we allow:

  • function calls
  • operators
  • getting properties

And the framework will compute what values does this expression depend on and do a minimal update when neccessary.

Binders

  • value value of input element
  • checked checkbox or radio is checked
  • disabled disabled based on an expression
  • text binds content text to an expression
  • html binds inner html to an expression
  • style-* binds extra style name on a value, for example: notification_bar: {'style-color': 'error ? "white" : "black"', 'style-background-color': 'error ? "red" : "yellow"'}.
  • class-* binds extra class name on a value, for example: foo: {'class-flat': 'useFlatTheme'}
  • if element exist or not, based on the expression value

Other binders like src, href, ... will reflect to element attributes.

There is no each binder, the complexity of rendering each binders is beyond what a simple data binding framework can do.

Caveats

It is a very simple data binding, elements won't refresh if you change nested data like: this.someData.foo = bar.

Instead, you can: this.someData.foo = bar; this.someData = this.someData; // triggers update.

You can only use instance method in a function call in the binder expression, and the method must be pure.