
Product
Socket for Jira Is Now Available
Socket for Jira lets teams turn alerts into Jira tickets with manual creation, automated ticketing rules, and two-way sync.
angular-virtual-dom
Advanced tools
[](http://badge.fury.io/js/angular-virtual-dom) [](http://badge.fury.io/bo/angular-virtual-dom)
angular-virtual-dom is an experimental Virtual DOM based AngularJS view renderer designed to be used with immutable data structures such as immutable-js and mori.
angular-virtual-dom lets you use regular AngularJS templates and expressions to bind data to the DOM, but uses Virtual DOM diffing behind the scenes.
angular-virtual-dom supports extensibility using directives - though only with directives that are Virtual DOM aware. That means angular-virtual-dom is not a drop-in substitute for the AngularJS directive compiler, and is meant to be used in limited contexts.
angular-virtual-dom works with AngularJS versions 1.2 and newer.
angular.module('myModule', ['teropa.virtualDom'])
.controller('MyCtrl', function($timeout) {
this.myData = Immutable.fromJS({
cols: [
{name: 'One', cssClass: 'one', key: 'one'},
{name: 'Two', cssClass: 'two', key: 'two'}
],
rows: [
{one: 'A1', two: 'B1'},
{one: 'A2', two: 'B2'}
]
});
// A new version of the immutable data structure triggers
// DOM diffing later.
$timeout(function() {
this.myData = this.myData.updateIn(['rows'], function(rows) {
return rows.push(Immutable.Map({one: 'A3', two: 'B3'}));
});
}.bind(this), 1000);
});
<div ng-controller="MyCtrl as myCtrl">
<table v-root="myCtrl.myData">
<thead>
<th v-repeat="col in myCtrl.myData.get('cols')"
class="{{col.get('cssClass')}}">
{{col.get('name')}}
</th>
</thead>
<tbody>
<tr v-repeat="row in myCtrl.myData.get('rows')"
class="{{$even ? 'even' : 'odd'}}">
<th v-repeat="col in myCtrl.myData.get('cols')">
{{row.get(col.get('key'))}}
</th>
</tr>
</tbody>
</table>
</div>
v-root establishes a Virtual DOM tree. The table tag and all of its descendants will be rendered using virtual-dom, bypassing Angular's own DOM compiler.myCtrl.myData changes. The whole Virtual DOM tree uses a single (reference) watch, and only when it fires does the view re-render. The idea is to attach an immutable data structure on the scope, refer to it in v-root, and let Virtual DOM diffing take care of updates when new versions of the data structure are produced.v-root.npm install angular-virtual-dom
Require the module and include it in your AngularJS modules:
require('angular-virtual-dom')
angular.module('myModule', ['teropa.virtualDom'])
Or just:
angular.module('myModule', [
require('angular-virtual-dom')
])
The library is available as a Bower dependency:
bower install angular-virtual-dom --save
After installation, add one of the following to your loaded scripts:
angular-virtual-dom/release/angular-virtual-dom.jsangular-virtual-dom/release/angular-virtual-dom.min.jsFinally, include the teropa.virtualDom module in your AngularJS modules:
angular.module('myModule', ['teropa.virtualDom'])
Use the v-root directive in your Angular templates to establish a Virtual DOM. This will short-circuit Angular's normal DOM compilation and build the Virtual DOM template from the contained elements.
The directive accepts an expression, and changes to that expression's value cause the Virtual DOM tree to be re-rendered:
<div v-root="baseData">
<!--
Nested DOM structures built into a Virtual DOM
tree
-->
</div>
Within a v-root, any AngularJS expressions are evaluated whenever DOM diffing occurs:
<div v-root="baseData">
<h1 class="{{anExpression}}">
{{anotherExpression}}
</h1>
</div>
Typically, though not necessarily, the expressions will access data from the data structure referred to in v-root:
<div v-root="baseData">
<h1 class="{{baseData.headerClass}}">
{{baseData.headerText}}
</h1>
</div>
Includes the node in the Virtual DOM only when the expression evaluates to a truthy value. Analogous with ng-if.
<div v-root="baseData">
<h1 v-if="{{baseData.headerText}}">
{{baseData.headerText}}
</h1>
</div>
Includes a collection of nodes in the Virtual DOM, for each item in a collection. Analogous with ng-repeat.
Supports at least the following types of collections:
Should additionally support any ES6 iterable collections.
Usage with sequential data structures:
<ul v-root="data">
<li v-repeat="item in data">
{{item}}
</li>
</ul>
Usage with associative data structures:
<ul v-root="data">
<li v-repeat="(k, v) in data">
{{k}}: {{v}}
</li>
</ul>
Additionally makes the special variables $index, $even, and $odd available within the template scope.
Note: The directive API should be considered highly unstable.
Virtual DOM directives are registered as normal AngularJS directives, but must define a linkVirtual function in the directive definition object. This should be a pure function that take a Virtual DOM node as an argument, and returns a modified Virtual DOM node or collection thereof.
The Virtual DOM nodes used by this library always hold a $scope attribute, referring to the current scope. A directive may create a new scope and attach it to the $scope attribute of the returned node.
While angular-virtual-dom is designed to be used with immutable data structures, it is not a hard requirement. Regular, mutable JavaScript data structures and objects work just as well.
You will, however, need to manually trigger re-renders by reassigning v-root to a new value unless your code does so naturally.
Use Github issues for requests.
Tero Parviainen (@teropa on Twitter)
Leans heavily on virtual-dom by Matt-Esch.
FAQs
[](http://badge.fury.io/js/angular-virtual-dom) [](http://badge.fury.io/bo/angular-virtual-dom)
We found that angular-virtual-dom demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket for Jira lets teams turn alerts into Jira tickets with manual creation, automated ticketing rules, and two-way sync.

Company News
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.

Security News
NIST will stop enriching most CVEs under a new risk-based model, narrowing the NVD's scope as vulnerability submissions continue to surge.