Simple. Fast.
Reactive.

A lightweight, pragmatic solution for adding reactive data binding to your existing HTML. No build tools required.

Get Started View Demo
// Zero setup. Just drop it in.
const app = dataBind.init(document.body, {
  count: 0,
  increment() {
    this.count++;
  }
});
// html
<body>
  <span data-bind-text='count'></span>
  <button data-bind-click='increment'>increment</button>
</body>
0
✨

Simple

Just HTML + JavaScript. No JSX, no virtual DOM, no complex build pipelines. It just works.

⚡

Fast

Extremely small footprint (~15KB) and high performance. Updates only what needs to change.

Compare dataBind with React 19

🔄

Reactive

Automatic UI updates when data changes using modern JavaScript Proxies. Like Vue 3, but simpler.

Declarative Bindings

Use simple data-bind-* attributes to connect your UI to your data. Supports text, events, loops, conditionals, and two-way binding out of the box.

  • ✓ data-bind-text
  • ✓ data-bind-model
  • ✓ data-bind-click
  • ✓ data-bind-dblclick
  • ✓ data-bind-change
  • ✓ data-bind-input
  • ✓ data-bind-submit
  • ✓ data-bind-blur
  • ✓ data-bind-focus
  • ✓ data-bind-hover
  • ✓ data-bind-if
  • ✓ data-bind-show
  • ✓ data-bind-for
  • ✓ data-bind-switch
  • ✓ data-bind-case
  • ✓ data-bind-default
  • ✓ data-bind-css
  • ✓ data-bind-attr
  • ✓ data-bind-tmp
  • ✓ data-bind-comp
<div id="app"> <h1 data-bind-text="title"></h1> <ul> <li data-bind-for="item in items"> <span data-bind-text="item.name"></span> </li> </ul> <input data-bind-model="newItem"> <button data-bind-click="add">Add</button> </div>

Documentation

dataBind.js is a drop-in JavaScript library that requires no build tools or compilation. Simply include the script tag and start using declarative data bindings in your HTML. Click on any binding below to see examples and learn how to use them.

data-bind-text ▼

Display text content from your viewModel. Supports deep property paths.

<h1 data-bind-text="title"></h1> <p data-bind-text="user.name"></p>
data-bind-model ▼

Two-way data binding for form inputs. Automatically syncs input values with your viewModel.

<input type="text" data-bind-model="username">
data-bind-click ▼

Handle click events. The handler receives the event and element as parameters.

<button data-bind-click="handleClick">Click Me</button> const viewModel = { handleClick(event, element) { console.log('Clicked!', event, element); } };
data-bind-change ▼

Handle change events on form inputs. Receives event, element, newValue, and oldValue.

<input data-bind-change="handleChange" data-bind-model="username"> const viewModel = { handleChange(event, element, newValue, oldValue) { console.log('Changed from', oldValue, 'to', newValue); } };
data-bind-for ▼

Render lists from arrays. Use $index for the current index and $root to access the root viewModel.

<div data-bind-for="item in items"> <p data-bind-text="item.name"></p> <button data-bind-click="$root.deleteItem($index)">Delete</button> </div> const viewModel = { items: [ { name: 'Item 1' }, { name: 'Item 2' } ], deleteItem(index) { this.items.splice(index, 1); } };
data-bind-if ▼

Conditionally render elements. Removes element from DOM when condition is false.

<div data-bind-if="isLoggedIn"> <p data-bind-text="user.name"></p> </div>
data-bind-show ▼

Toggle element visibility with CSS. Element stays in DOM but is hidden when condition is false.

<div data-bind-show="isVisible"> <p>Visible content</p> </div>
data-bind-switch / case / default ▼

Switch statement for multiple conditions. Only the matching case will be rendered.

<div data-bind-switch="currentState"> <div data-bind-case="loading">Loading...</div> <div data-bind-case="error">An error occurred</div> <div data-bind-case="success">Data loaded successfully!</div> <div data-bind-default>Please wait...</div> </div>
data-bind-css ▼

Dynamically add/remove CSS classes based on conditions or bind a string of class names.

<div data-bind-css="{ active: isActive, disabled: !isEnabled }"></div> <div data-bind-css="dynamicClass"></div>
data-bind-attr ▼

Dynamically set element attributes from a function or object in your viewModel.

<img data-bind-attr="getImageAttrs"> const viewModel = { getImageAttrs() { return { src: 'image.jpg', alt: 'Description' }; } };
data-bind-tmp ▼

Render templates with data from your viewModel.

<div data-bind-tmp="{id: 'userCard', data: 'user'}"></div> <template id="userCard"> <div class="card"> <h2 data-bind-text="name"></h2> <p data-bind-text="email"></p> </div> </template>
data-bind-submit ▼

Handle form submit events.

<form data-bind-submit="handleSubmit"> <input data-bind-model="username"> <button type="submit">Submit</button> </form>
data-bind-blur ▼

Handle blur events when an element loses focus.

<input data-bind-blur="onBlur">
data-bind-focus ▼

Handle focus events when an element receives focus.

<input data-bind-focus="onFocus">
data-bind-dblclick ▼

Handle double-click events.

<div data-bind-dblclick="onDblClick">Double-click me</div>
data-bind-hover ▼

Handle hover in and out events.

<div data-bind-hover="onHover">Hover over me</div>
data-bind-input ▼

Handle input events as user types (fires on every keystroke).

<input data-bind-input="onInput" data-bind-model="search">
data-bind-comp ▼

Identifier attribute for selecting component elements. Use it to target specific parts of your page for dataBind initialization.

<div data-bind-comp="todos"> <!-- todo list content --> </div> const component = dataBind.init( document.querySelector('[data-bind-comp="todos"]'), viewModel );