An easy-to-use Virtual DOM built for the web!

Welcome to diffHTML! An opinionated UI framework designed to create reactive user interfaces. You can start using it quickly without much upfront knowledge, and opt-into more powerful features as you go.

Hello world!

With diffHTML, you are able to start building a reactive UI quickly, without needing lots of upfront knowledge. You are able to start gracefully and improve the integration as your requirements change, and harness more features.

import { innerHTML } from 'https://diffhtml.org/es';

innerHTML(document.body, `
  <div>Hello world!</div>

Core features

Getting the source

There are two builds of diffHTML. The first and most common is the primary build which contains a lightweight HTML parser. It is slightly larger than the second build, which is referred to as the runtime build. This second build is meant for pairing with output that has been optimized with the Babel plugin.

If you are just getting started, ignore the runtime build for now.


Use a JavaScript package manager to install locally.

Now tools using the Node module resolution algorithm, like Node and webpack, can find diffHTML when it is attempted to be required.

const { innerHTML } = require('diffhtml');

To load the runtime build use:

const { innerHTML } = require('diffhtml/dist/cjs/runtime');

Script tag

Use this tag in HTML to load diffHTML globally.

<script src="https://unpkg.com/diffhtml/dist/diffhtml.min.js"></script>

  diff.outerHTML(document.body, `<body>Hello world!</body>`);

To load just the runtime:

<script src="https://unpkg.com/diffhtml/dist/diffhtml.min.js"></script>

ES modules

You can import diffHTML directly over HTTP using the ES modules syntax. This is a new feature that isn't available in all browsers yet, but you can use them safely in nearly all modern browsers .

import { innerHTML } from 'https://unpkg.com/diffhtml?module';
// or 
import { innerHTML } from 'https://diffhtml.org/es';

To load just the runtime:

import { innerHTML } from 'https://unpkg.com/diffhtml/runtime?module';
// or
import { innerHTML } from 'https://diffhtml.org/es/runtime';

Using import maps

Import maps are a new new feature only available in modern Chrome which allow you to specify a configuration to import global names instead of using URLs or file paths directly.

For instance, you can convert:

import { innerHTML } from 'https://diffhtml.org/es';


import { innerHTML } from 'diffhtml';

Which will resolve to the same URL.

This is accomplished by adding a script tag to your web application that specifies the configuration as JSON. And looks something like this:

<script type="importmap">
  "imports": {
    "diffhtml": "https://diffhtml.org/es",
    "diffhtml/components": "https://diffhtml.org/master/diffhtml-components/dist/es"

Remember this is JSON so you cannot have trailing commas or use single quotes. It is also currently limited to being inline with the markup, it cannot be an external file.

Optimizing builds

The Babel plugin is useful after you have a working project and wish to optimize it at build time. The Babel plugin will perform numerous optimizations to your code depending on how it is written and structured. For instance, anytime you have an element that does not change, the call will be hoisted and reused instead of recreated every time. Any html tagged template calls will be converted to createTree calls.

After your code has been passed through this plugin, you will be able to fully utilize the runtime build!

To use, install into your project as a dev dependency.

npm install -D babel-plugin-transform-diffhtml

Specify the plugin in the Babel configuration, usually a .babelrc or babel.config.js file:

  "plugins": ["babel-plugin-transform-diffhtml"]

Take this code as an example input:

const { innerHTML, html } = require('diffhtml');

function render() {
  innerHTML(document.body, html`
    <div>Hello world</div>

Without this Babel transformation process, this HTML would need to be parsed every time render() is called. If you use the runtime build and the parser, this will become a cached call. html is the same thing as createTree in the runtime build. So there is no HTML parsing happening.

const { innerHTML, html } = require('diffhtml/dist/cjs/runtime');

function render() {
  innerHTML(document.body, html('div', {}, [html('#text', null, 'Hello world')]));

Refer to the configuration documentation.

Edit on GitHub