# JsViews brings data binding to JsRender templates with one link call

> JsViews is a JavaScript library that takes JsRender templates and makes them data-bound, adding observable data and an MVVM layer on top of jQuery. A template tag or a data-link attribute is enough to bind markup to your objects, and link() renders, inserts and binds in a single call. The cost is a hard dependency on jQuery and a binding model built around template markup.

**BorisMoore/jsviews** — Interactive data-driven views, MVVM and MVP, built on top of JsRender templates

- Repository: https://github.com/BorisMoore/jsviews
- Website: http://www.jsviews.com/#jsviews
- Stars: 864 · Forks: 129
- Language: JavaScript
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/borismoore-jsviews

## Binding lives in the template, not in a component

JsViews is described as a next-generation MVVM and MVP framework built on top of JsRender templates. The relationship is straightforward: JsRender renders a template into a string of HTML, and JsViews adds data binding and observable data on top of that, so the rendered result stays in step with your data.

The design decision is where the binding is expressed. In most template systems you write a component, register it, and pass properties. Here you write a tag inside a template. Any JsRender tag, {{...}}, becomes data-linked when you write it as {^{...}}, and any HTML element can be bound with a data-link attribute.

The effect on the DOM is the same as a component system: change the data and the view updates itself. The effect on the code is different. There is no separate component definition to write, no virtual DOM, and no diffing layer described in the documentation. The template is the view, and the object is the model.

The project also positions itself against its own predecessors. JsRender and JsViews together are the current implementation of the official jQuery plugins jQuery Templates and jQuery Data Link, and the README says they supersede those libraries. That tells you where the design came from and how much of the API surface you will recognise if you have used those plugins.

The npm package is named jsviews, and its single runtime dependency is jQuery.

## Two ways to write a binding

The binding syntax comes in two forms, and the distinction between them is the whole mental model.

The first is a linked tag. Any JsRender tag written as {^{...}} is data-linked, and the README gives a list example where the list updates when the people array changes and the name property updates inside it.

```html
<ul>
  {^{for people}} <!--List will update when people array changes-->
    <li>{^{:name}}</li> <!--Will update when name property changes-->
  {{/for}}
</ul>
```

The second is a linked element, using a data-link attribute on the HTML itself:

```html
<input data-link="name"/> <!--Two-way data-binding to the name property-->
<span data-link="name"></span> <!--Will update when name property changes-->
```

The input is two-way, so typing in it changes the underlying property, and that change can then trigger updates elsewhere in the templated UI. The span is one-way, showing the value without accepting edits.

That asymmetry is the useful part. In a form, the fields are two-way so the model stays current; in a status label or a counter elsewhere on the page, the binding is one-way so the user cannot corrupt the model by editing a derived value. The README notes that elements in the top-level page content can be data-linked as well, so a binding does not have to live inside a template.

## link() replaces render plus insert plus bind

With JsRender you call render() to produce a string and then put it into the DOM yourself:

```js
var html = tmpl.render(data, helpersOrContext);
$("#container").html(html);
```

JsViews collapses that into one call:

```js
tmpl.link("#container", data, helpersOrContext);
```

The README lists what that single line does: it renders the template, it inserts the resulting HTML as content under the container element, and it data-links that content to the underlying data. Observable changes in the data then trigger updates in the rendered UI without further calls from your code.

The smallest complete example uses a template built from a string:

```js
var tmpl = $.templates("{^{:name}} <input data-link='name' />");
var person = {name: "Jim"};
tmpl.link("#container", person);
```

After the call the container holds the rendered text and the input, with the name property bound to the text node and two-way bound to the input, so editing the field updates the object.

There are two ways to reach link(). If you hold a reference to the template object you call template.link(...). If you registered the template by name, for example "myTmpl", you call link.myTmpl(...), which is how the named-template examples work with $.templates and $.link.myTmpl1.

## Named templates, script blocks and top-level linking

Templates do not have to live in strings. The README shows a script block with the type text/x-jsrender, which is how a template is kept in the page and registered by selector:

```html
<script id="myTemplate" type="text/x-jsrender">
{^{:name}} <input data-link="name" />
</script>
```

That template is then picked up with $.templates("#myTemplate") and linked with tmpl.link("#container", person), or registered by name with $.templates("myTmpl1", ...) and linked through $.link.myTmpl1("#container", person).

Top-level linking is the other feature worth knowing. A call with true as the first argument activates the declarative data-binding expressions on a target element and on elements inside its content:

```js
$.link(true, "#target", data);
```

That is what makes the library usable in pages that are not entirely template-driven, where a piece of the interface was written by hand and only needs to be bound to existing data.

The repository makes the same point in its layout. Beside the library files, jquery.views.js, jquery.observable.js, jsrender.js and jsviews.js, with their minified versions and source maps, there is a demos directory, a test directory, a typescript folder with the type definitions referenced from package.json, a bower.json and a gulpfile.js. The npm entry point is ./jsviews.js and the type definition path is ./typescript/jsviews/index.d.ts.

## Getting jsviews onto a page

The installation options are the usual jQuery-era set, and the README lists all of them.

The library file is available from the downloads page on jsviews.com. For CDN delivery there is jsdelivr at the package path npm/jsviews, and cdnjs with the library jsviews. The README also points at a Bower install:

```bash
bower install jsviews
```

Script loaders work too, with an AMD loader such as RequireJS named explicitly. For Node.js projects the README refers to separate pages in the manual for using JsViews as a Browserify module and as a webpack module, which is the path to take if you want it bundled rather than loaded from a CDN.

One detail saves an afternoon of debugging. The note under the installation section says that jsviews.js includes all of the jsrender.js code, so jsrender.js does not need to be loaded first. If you load both files in the wrong order you will end up with two template engines on the page and a very confusing error.

The package declares jquery ^3.7.1 as a dependency, and the newest release, v1.2.0 published on 2026-06-25, is titled jQuery 4 compatibility, which suggests the library is maintained against the newer jQuery line as well.

## Where the approach strains

Three limitations are worth weighing before you build on this.

The first is the jQuery dependency, and it is not optional in practice. The whole binding surface is expressed through jQuery plugins, with $.templates and $.link as the entry points, and the npm package lists jquery as a runtime dependency. On a project that has already decided to drop jQuery, this library is not a candidate, and the tie to jQuery 4 compatibility is a maintenance promise rather than an escape from the dependency.

The second is that the model of the view is the template. There is no component abstraction, so a project that expects reusable widgets with their own state, or a virtual DOM that patches only what changed, will find the shape unfamiliar. The update mechanism is property-level binding over plain objects rather than a diff of a component tree.

The third is the observable data layer. The jquery.observable.js file exists in the repository and the API page is linked from the site, but the section on making observable changes to objects and arrays is the place to study how a change is detected and propagated. Anyone evaluating the library should read that section in the manual before committing, because it is the piece that determines whether your objects can be plain or need to be wrapped.

The library also dates from the jQuery era. Its own successor path is the Data Link and Templates plugins it replaced, and the samples, demos and test suite in the repository reflect that period.

## Conclusion

Adopt JsViews when your team already ships jQuery, wants a small template-centric binding layer instead of a full component framework, and is willing to keep data in plain objects with observable change tracking. Do not adopt it for a greenfield application where a component model and a build-time toolchain are expected, because the whole mechanism hangs on jQuery and on markup attributes. Before you commit, check the release notes against your jQuery version, since version v1.2.0 published on 2026-06-25 is the one labelled jQuery 4 compatibility while package.json still depends on jquery ^3.7.1, and read the observable data section of the manual before committing.

## FAQ

### What is the difference between JsRender and JsViews?

JsRender renders templates into strings for insertion into the DOM, while JsViews adds data binding, observable data and MVVM support on top of it. The README notes that jsviews.js includes the jsrender.js code, so jsrender.js does not have to be loaded first.

### How do I bind an input field to a data property in JsViews?

Add a data-link attribute naming the property, for example an input with data-link="name", which gives two-way binding so user edits update the underlying object. A span with the same attribute is one-way and only displays the value.

### How do I install the jsviews package?

The library file comes from the downloads page on jsviews.com, or from the jsdelivr and cdnjs CDNs. The README also documents a Bower install with bower install jsviews, loading through an AMD loader such as RequireJS, and separate manual pages for using JsViews with Browserify or webpack.

### Does JsViews support jQuery 4?

Version v1.2.0, published on 2026-06-25, is titled jQuery 4 compatibility, while the package.json dependency is still jquery ^3.7.1. The last push to the default branch was on 2026-10-18 and the earlier tags are v1.0.16 from 2025-05-22 and v1.0.15 from 2024-07-14.

## Sources

- [BorisMoore/jsviews on GitHub](https://github.com/BorisMoore/jsviews)
- [License: MIT](https://github.com/BorisMoore/jsviews/blob/master/LICENSE)
- [Project website](http://www.jsviews.com/#jsviews)
- [README](https://github.com/BorisMoore/jsviews/blob/master/README.md)
- [Releases](https://github.com/BorisMoore/jsviews/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/borismoore-jsviews
