Compile Jade templates to Hyperscript for Virtual DOM libraries
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Build status Test coverage

Compile your jade templates into Virtual DOM functions. Works with multiple Virtual DOM libraries, including:

For people who like declarative reactive templating, but don't like writing HTML or JSX.

Create a template:

  each item in items
      .item-title= item.title
      .item-description= item.description

require() your template as a function and use a rendering system like main-loop:

const mainLoop = require('main-loop');

const template = require('./items.jade');

const initState = {
  items: [],

const loop = mainLoop(initState, template, {
    create: require("virtual-dom/create-element"),
    diff: require("virtual-dom/diff"),
    patch: require("virtual-dom/patch"),

Then update whenever you'd like!

  items: [
      id: 'asdf',
      title: 'some title',
      description: 'some description',
      active: false,


  • For easy configuration with Webpack, use virtual-jade-loader.
  • To translate with Babel, use babel-plugin-virtual-jade.
  • Can be used with any CommonJS environment with client-side require()s.
  • All templates must return a single root element.
  • Requires you to install the appropriate virtual-dom library in your top-level app.


fnStr = render(str, options)

str is the jade source as a string. fnStr is output JS that you should include as a CommonJS module.

Options are:

  • filename: path and name of Jade source file for str. Required if you use include or extends in templates.
  • marshalDataset=true: whether to convert data- attributes to dataset members. Set to false to treat as props with the same name as the attributes (if your target Virtual DOM renderer does not support the dataset API).
  • pretty=false: whether to beautify the resulting JS. Requires you to install js-beautify yourself.
  • propsWrapper: optional object to wrap Jade attributes in; for example, with propsWrapper = 'props', the template div(foo="bar") will translate to something like h('div', {props: {foo: 'bar'}}) rather than h('div', {foo: 'bar'})
  • rawProps: whether to skip Jade attribute -> HTML property conversion; this is set to true in the default Snabbdom configuration
  • runtime: optional override to include any arbitrary Virtual DOM library that defines the h() hyperscript function. E.g. var h = require('my-special-lib/h');
  • vdom: name of the Virtual DOM library configuration to load (currently either virtual-dom or snabbdom).

Returns a string that looks like:

function render(locals) {
  var result_of_with = /* stuff */
  if (result_of_with) return result_of_with.value;;

You are expected to eval() the string if you want the source as a function. Otherwise, just create a module in the following format:

const js = `module.exports = ${fnStr}`;