My small secret web weapon to bind things – rivets.js

Hey, I need something. Uumm. Yeah, I need... JavaScript template engine! No? Something more? A small library that would bind data to existing DOM, locally! Yes!

rivets.js - it's not too popular but it works and it's only 26 KB minified without gzipping (which would go to just 6 KB!). Let's go through it's features and see some snippets I've developed through few months.

Story short - what the library is

  • developed with CoffeeScript
  • small but rather feature complete + extensible
  • not as big as AngularJS
  • so it just binds things
  • and it's much more than simple templating systems like swig or nunjucks
  • it's reactive on data change
  • flexible through custom formatters, binders, adapters and components

Community right now is rather small and original author doesn't seem maintaining it anymore but there are other people who do the job. Somewhat passively, I'm one of them and I hope this post would be a useful contribution.

The engine + compare to AngularJS

  • rivets formatters are like Angular filters - those get the value and transform it to something else.
  • rivets binders are like Angular directives - those get element and optional value passed in.
  • rivets components are like Angular 1.5 components or Angular directives used as a components.
  • adapters probably don't exist in Angular because...
  • Angular usually takes JavaScript expressions while rivets uses much more simplier custom format for expressions
  • so rivets adapters are a way to register custom operators for watching objects differently.
  • Angular does dirty checking by marking objects while rivets overwrites setters in Objects to notify the engine about changes. The latter mechanism is sometimes called to be reactive.

Performance may not be great since there is no Virtual DOM or similiar fancy technique. However, there's a reactiveness to data change which makes some little promise. Also, there's rv-if which happens to be a mix between ng-if and ng-show.

Talk is cheap. Show me the code!

Let's train on an example - a list of github repositories with custom tags:

a showcase of few tricks with rivets

Let's say we have a collection of GitHub repositories ( repos) where each one of them can be tagged (has a collection of  tags).

This is our scope defined in TypeScript using class syntax:

See the arrow functions? It's important to have them due to definition of this  keyword in call context made by rivets. After transpilation to JavaScript it would look like this:

Another option would be to use simple object with properties:

There's a nuance about this  keyword which may break all your code. Read the "nuance about this keyword" chapter in the next article about details to understand the issue.

Let's get back to the example - fill  repos with:

Now, the view:

Let's highlight some things in the HTML above:

  1. every attribute prefixed with rv-  is a binder
  2. (by default) data is bound in 2 ways:
    1. rv-value  directive which is a two-way binding
    2. one-way text binding using curly braces in element's content, e.g. { tag }
  3. you can show/hide elements conditionally using built-in rv-if binder
  4. you can loop collection using built-in rv-each-*  binder
  5. you can toggle classes using built-in rv-class-*  binder
  6. you can chain formatters, i.e. they launch one after another, e.g.  rv-if="filter | equals 'untagged' | not" where equals is the first launched formatter (with value "untagged") and not is second (without additional value). The second one is called with an argument which is a result of previous formatter (the equals )
  7. you can register on events using rv-on-* binder, e.g. rv-on-change , rv-on-click

However, few things are mysterious since they're not built-in:

  • formatters: isEmpty , equals , not
  • passing args  to function call!

Let's define them!

Finally, let's bind the scope with element of id="app" (defined in view):

Full example

To see this example live open the plunker:
Example for rivets.js - presenting basic features

Also, you can take a look at bigger example which is a source of the small plunker:
→ Namek/github-star-tagger-chrome


There's some learning curve due to it's syntax which is really simple in terms of implementation but you can't have JavaScript expressions as we used to have in AngularJS. That's especially visible with chained formatters.

As this library is pretty small there is more to learn to have more power. Follow the next part:

Binding with rivets.js - details and tricks