The easy-to-use Virtual DOM, built for the web!


This concept allows developers to write plugins that augments diffHTML to do different things. You can use pre-made middleware or create your own easily.

Inline Transitions

GitHub repo link

Tiny module to support binding/unbinding declarative diffHTML transition hooks.

npm install diffhtml-middleware-inline-transitions

Full events and args list:

Event Name Args
onattached (eventTarget, domNode)
ondetached (eventTarget, domNode)
onreplaced (eventTarget, oldNode, newNode)
onattributechanged (eventTarget, oldNode, attributeName, oldValue, newValue)
ontextchanged (eventTarget, oldNode, oldValue, newValue)


Apply to an element by passing the function to the associated state name:

import $ from 'jquery';
import { innerHTML, html, use } from 'diffhtml';
import inlineTransitions from 'diffhtml-middleware-inline-transitions';

// Enable the monitoring of attributes for changes.

// Use jQuery to return a promise and fade in the body and paragraph.
function fadeIn(body, domNode) {
  return $(domNode).fadeOut(0).fadeIn(1000).promise();

innerHTML(document.body, html`<body onattached=${fadeIn}>
  <p>Watch me fade in slowly!</p>


GitHub repo link

Use with diffHTML to console.log out render Transaction operations. This will nest sub-component renders if they happen during a parent render.

npm install diffhtml-middleware-logger


import { use } from 'diffhtml';
import logger from 'diffhtml-middleware-logger';


This is not a very performant middleware, so please do not use this in production where performance is critical. Use only in development or behind a flag.

Service Worker

GitHub repo link

While this does not really benefit from being a middleware, I made it as such since it looks nice in the use and can be disabled if the middleware is unsubscribed. I've added some developer niceties, like auto clearing the caches for development. It's also possible to disable the worker completely if you get annoyed with some behavior.

npm install diffhtml-middleware-service-worker


import { use } from 'diffhtml';
import serviceWorker from 'diffhtml-middleware-service-worker';

// Defaults shown, these are all optional values.
  url: '/service-worker.js',
  scope: '/',
  autoClearCaches: location.search.includes('diff_autoclear'),
  disable: location.search.includes('diff_disable'),
  quiet: location.search.includes('diff_quiet'),
  options: {},

Synthetic Events

GitHub repo link

Changes the event binding from inline event handlers like onclick = fn to use addEventListener. Hooks are attached to the body element and coordinated using event delegation.

npm install diffhtml-middleware-synthetic-events


import { use, html, innerHTML } from 'diffhtml';
import syntheticEvents from 'diffhtml-middleware-synthetic-events';


function render() {
  return html`
    <div onclick=${e => console.log(e)} />

// Binds the event on div using `addEventListener`.
innerHTML(document.body, render());

A good use case for this middleware is building a Chrome Extension where using inline event handlers is not possible. Supports non-bubbling events via the useCapture flag.

Verify State

GitHub repo link

Asserts that a render properly updated the old Virtual Tree and the DOM. Will recursively search for inconsistencies, displays warnings unless debugging is enabled, then it throws errors instead.

npm install diffhtml-middleware-verify-state


import { use } from 'diffhtml';
import verifyState from 'diffhtml-middleware-verify-state';

// Throw when debug is truthy (when location.search has `?debug`)
use(verifyState({ debug: location.search.includes('debug') }));

Edit on GitHub