One of the most powerful two way data-binding tool with virtualization. Highly optimized for performance and memory

Data binding

One of the most powerful two-way data-binding tools available. It has a bunch of really cool features:

  • It can be extended with plugins so that virtually any behavior can be triggered on model update.
  • It can generate DOM elements for you based on a pure HTML template and repeat them to render a list of items.
  • The rendering of lists of items can be virtualized so that not all of the items get rendered, improving performance and memory consumption.
  • It's so fast that it's the perfect tool for mobile devices too.
  • It's extensively tested to prevent memory leaks.
  • It's a Seam plugin, so it's easy to use.
  • It even works with SVGs!

Live example

There's a virtualized grid displaying 1,000,000 items showcased here


npm install data-binding-plugin

How to use

data-binding-plugin requires three things:

  • An observable data store, so that the data-binding plugin can listen to changes events
  • An HTML/SVG template that declares where the data will be rendered
  • Seam that will make understand the declarative bindings for data-binding

Require data-binding-plugin:

var DataBinding = require("data-binding-plugin");

The data-binding plugin binds the data from a model with an HTML view.

Initialize data-binding:

var dataBinding = new DataBinding();

Give it a model (an observable-store)

var Store = require("observable-store");
var store = new Store({
    name: "data-binding"

Give the store to the data-binding plugin:


The data-binding is a Seam plugin, so we need to new up Seam and add the plugin to it:

var Seam = require("seam");
var seam = new Seam();
seam.add("bind", dataBinding);

Now we can define the view. Whenever the name property is updated in the store, the innerHTML property of the DIV element is set with the value.

<div data-bind="bind: innerHTML, name"> </div>

And apply the data-binding plugin to the view.


When the store is updated, the view will reflect the change:

store.set('name', 'data-binding-plugin');

The data-binding plugin can update any property. This will update the className, which in turn sets the class attribute of the div element.

<div data-bind="bind: className, class"></div>

Of course, a template can have several bindings:

<div data-bind="bind: className, gender">
    <span data-bind="bind: innerText, name"></span>
    <span data-bind="bind: innerText, email"></span>

We can also have formatter. Instead of giving a className, we can specify a formatter function:

<div data-bind="bind: formatDate, date"></div>

And when initializing the plugin, we add it a list of formatters:

var dataBinding = new DataBinding(model, {
    formatDatefunction (date) {
        // this is the dom element 
        this.innerHTML = formatDate(date);

Several parameters can be given to the formatter:

<div data-bind="bind: formatDate, date, BST, ..."></div>
formatDatefunction(datetimezone, ...) {

Data-binding plugin can also repeat a template if the model is an array:

<ul data-bind="foreach">
        <span data-bind="bind: innerText, firstname"></span>
        <span data-bind="bind: innerText, lastname"></span>

With an array-based observable-store:

var store = new Store([{
    firstname: 'Mia',
    lastname: 'Wallace'
    firstname: 'John',
    lastname: 'McLane'

And when adding/updating/removing an item in the store, the DOM will be updated.

Finally, data-binding plugin comes with a virtualization option which allows you to render only parts of a longer list of items, so that only what's visible is actually rendered to save memory and improve performance:

<ul data-bind="foreach: list, 0, 10">
        <span data-bind="bind: innerText, firstname"></span>
        <span data-bind="bind: innerText, lastname"></span>

This list will render 10 items from index 0, and will be called 'list'. In JavaScript, we can instruct the list to display the next items:

var itemRenderer = dataBinding.getItemRenderer('list');
// start from index 10 
// display 20 items instead of 10 
// rerender the items 


  • Update all dependencies to latest version
  • Update all dev dependencies
  • Fix license field in package.json