tools to work with a virtual dom
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


tools to work with a virtual dom

Build Status Coverage Status Dependency Status


React is probably the first to have done this and gain massive hype with it. However it grew extremely large, being >500k unminified.

mithril.js also has a virtual dom and claims to do dom diffing. However, it is a complete MVC framework, complete with its own promises implementation, xhr, etc. But at least it is very small, although not very readable.

virtual-dom/ mercury seems like a very good solution. It has a lot more flexibility and deals with properties instead of with attributes by default.

And of course, I don’t want to merely use a library. I want to know and understand the technology, so I might as well implement it myself :-)


$ component install Swatinem/virtualdom



Creates a virtual dom node for the real DOM node.


Creates a real DOM node for the virtual dom vnode.

diff(from, to)

Creates a list of patches to transform from to to.

applyPatch(node, patches)

Applies a list of patches, see below for patch details.

Internal data structures

Virtual DOM Node

A text node is simply a js string.

A comment node is {comment: 'comment content'}

And a normal node is represented as:

	key: 'optional internal identifier used for sorting',
	tag: 'div',
	ns: 'optional namespace, like "" for svg'
	class: ['array', 'of', 'classes'],
	style: {position: 'absolute', borderRadius: '5px'},
	data: {dataset: 'key value pairs'},
	attributes: {'id': 'id', 'value': 'key value pairs for attributes'},
	children: [array, of, children, or, a, single, child]

class, data and style are handled separately from other attributes since they have array or hashtable-like accessors in the real DOM.


	node: [], // chain of `childNodes` positions, starting at the room node
	// and patches, which are all optional:
	addClasses: [],
	removeClasses: [],
	setStyles: {},
	removeStyles: [],
	setAttributes: {},
	removeAttributes: [],
	setData: {},
	removeData: [],
	setContent: '', // for text and comment nodes
	childPatches: [/* see below */]
// and childPatches:
	type: 'insert',
	child: newChild,
	index: 0, // required, will insert at the specified index
	type: 'replace',
	child: newChild,
	index: 0, // required, index of the old child
	type: 'remove'
	index: 0
// might be good to have, but very difficult to implement as a diff
	type: 'move'
	from: 0, // old index
	to: 1 // new index


  • reorder / move child nodes
  • support innerHTML for unsafe code



Released as free software as part of ChatGrape