JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://rawgithub.com/mikeric/rivets/v0.5.13/dist/rivets.min.js"></script>
<script src="https://rawgithub.com/melanke/Watch.JS/master/src/watch.min.js"></script>
<div id="view">
  <section>
    <h1 data-text="item.title"></h1>
    <p>Binding text using data-text <code data-text="item.text"></code>.</p>
    <p>Text Value: <input data-input="item.text"></p>
  </section>
  <section>
    <p>
      Binding an array using data-each 
      <code><span data-text="item.tags | length"></span> tags</code>.
    </p>
    <p>
      <input data-value="item.newTag">
      <button data-on-click="vm.addTag">add</button>
    </p>
    <ul>
      <li data-each-tag="item.tags">
        <span data-text="tag.name"></span>
      </li>
    </ul>
  </section>
</div>

CSS

body {
  font-family: menlo, monospace;
  font-size: 12px;
}

h1 {
  font-size: 1.5em;
}

h1, p {
  margin: 0.5em 0 1em;
}

code {
  background-color: #fec;
  padding: 0.2em 0.5em;
}

section {
  border-bottom: 1px dashed #ddd;
  padding: 1em;
}

ul {
  list-style-type: disc;
  padding-left: 2em;
}

JavaScript

// CONFIGURE RIVETS.JS TO WORK WITH WATCH.JS

rivets.configure({
  adapter: {
    subscribe: function(obj, keypath, callback) {
      watch(obj, keypath, callback)
    },
    unsubscribe: function(obj, keypath, callback) {
      unwatch(obj, keypath, callback)
    },
    read: function(obj, keypath) {
      return obj[keypath]
    },
    publish: function(obj, keypath, value) {
      obj[keypath] = value
    }
  }
})

// LIVE INPUT CUSTOM BINDER

rivets.binders.input = {
  publishes: true,
  routine: rivets.binders.value.routine,
  bind: function(el) {
    el.addEventListener('input', this.publish)
  },
  unbind: function(el) {
    el.removeEventListener('input', this.publish)
  }
}
          
// LENGTH FORMATTER

rivets.formatters.length = function(value) {
  return value.length
}

// BINDING PLAIN JAVASCRIPT OBJECTS TO THE VIEW

var item = {
  title: "Rivets.js + Watch.js!",
  text: "change me",
  tags: [
    {name: "Data binding"},
    {name: "DOM-based templating"}
  ]
}
          
var viewModel = {
  addTag: function() {
    item.tags.push({name: item.newTag})
    item.newTag = ""
  }
}

var el = document.getElementById('view');

rivets.bind(el, {item: item, vm: viewModel})