SkillAgentSearch skills...

Snabbdom

A virtual DOM library with focus on simplicity, modularity, powerful features and performance.

Install / Use

/learn @snabbdom/Snabbdom
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<img alt="Snabbdom" src="https://raw.githubusercontent.com/snabbdom/snabbdom/master/readme-title.svg" width="356px">

A virtual DOM library with a focus on simplicity, modularity, powerful features and performance.


License: MIT Build Status npm version npm downloads Join the chat at https://gitter.im/snabbdom/snabbdom

Donate to our collective

Thanks to Browserstack for providing access to their great cross-browser testing tools.


English | 简体中文 | Hindi

Introduction

Virtual DOM is awesome. It allows us to express our application's view as a function of its state. But existing solutions were way too bloated, too slow, lacked features, had an API biased towards OOP , and/or lacked features I needed.

Snabbdom consists of an extremely simple, performant, and extensible core that is only ≈ 200 SLOC. It offers a modular architecture with rich functionality for extensions through custom modules. To keep the core simple, all non-essential functionality is delegated to modules.

You can mold Snabbdom into whatever you desire! Pick, choose, and customize the functionality you want. Alternatively you can just use the default extensions and get a virtual DOM library with high performance, small size, and all the features listed below.

Features

  • Core features
    • About 200 SLOC – you could easily read through the entire core and fully understand how it works.
    • Extendable through modules.
    • A rich set of hooks available, both per vnode and globally for modules, to hook into any part of the diff and patch process.
    • Splendid performance. Snabbdom is among the fastest virtual DOM libraries.
    • Patch function with a function signature equivalent to a reduce/scan function. Allows for easier integration with a FRP library.
  • Features in modules
  • Third party features

Example

import {
  init,
  classModule,
  propsModule,
  styleModule,
  eventListenersModule,
  h
} from "snabbdom";

const patch = init([
  // Init patch function with chosen modules
  classModule, // makes it easy to toggle classes
  propsModule, // for setting properties on DOM elements
  styleModule, // handles styling on elements with support for animations
  eventListenersModule // attaches event listeners
]);

const container = document.getElementById("container");

const vnode = h(
  "div#container.two.classes",
  { on: { click: () => console.log("div clicked") } },
  [
    h("span", { style: { fontWeight: "bold" } }, "This is bold"),
    " and this is just normal text",
    h("a", { props: { href: "/foo" } }, "I'll take you places!")
  ]
);
// Patch into empty DOM element – this modifies the DOM as a side effect
patch(container, vnode);

const newVnode = h(
  "div#container.two.classes",
  { on: { click: () => console.log("updated div clicked") } },
  [
    h(
      "span",
      { style: { fontWeight: "normal", fontStyle: "italic" } },
      "This is now italic type"
    ),
    " and this is still just normal text",
    h("a", { props: { href: "/bar" } }, "I'll take you places!")
  ]
);
// Second `patch` invocation
patch(vnode, newVnode); // Snabbdom efficiently updates the old view to the new state

More examples


Table of contents

Core documentation

The core of Snabbdom provides only the most essential functionality. It is designed to be as simple as possible while still being fast and extendable.

init

The core exposes only one single function init. This init takes a list of modules and returns a patch function that uses the specified set of modules.

import { classModule, styleModule } from "snabbdom";

const patch = init([classModule, styleModule]);

patch

The patch function returned by init takes two arguments. The first is a DOM element or a vnode representing the current view. The second is a vnode representing the new, updated view.

If a DOM element with a parent is passed, newVnode will be turned into a DOM node, and the passed element will be replaced by the created DOM node. If an old vnode is passed, Snabbdom will efficiently modify it to match the description in the new vnode.

Any old vnode passed must be the resulting vnode from a previous call to patch. This is necessary since Snabbdom stores information in the vnode. This makes it possible to implement a simpler and more performant architecture. This also avoids the creation of a new old vnode tree.

patch(oldVnode, newVnode);

Unmounting

While there is no API specifically for removing a VNode tree from its mount point element, one way of almost achieving this is providing a comment VNode as the second argument to patch, such as:

patch(
  oldVnode,
  h("!", {
    hooks: {
      post: () => {
        /* patch complete */
      }
    }
  })
);

Of course, then there is still a single comment node at the mount point.

h

It is recommended that you use h to create vnodes. It accepts a tag/selector as a string, an optional data object, and an optional string or an array of children.

import { h } from "snabbdom";

const vnode = h("div#container", { style: { color: "#000" } }, [
  h("h1.primary-title", "Headline"),
  h("p", "A paragraph")
]);

fragment (experimental)

Caution: This feature is currently experimental and must be opted in. Its API may be changed without a major version bump.

const patch = init(modules, undefined, {
  experimental: {
    fragments: true
  }
});

Creates a virtual node that will be converted to a document fragment containing the given children.

import { fragment, h } from "snabbdom";

const vnode = fragment(["I am", h("span", [" a", " fragment"])]);

toVNode

Converts a DOM node into a virtual node. Especially good for patching over pre-existing, server-side generated HTML content.

import {
  init,
  styleModule,
  attributesModule,
  h,
  toVNode
} from "snabbdom";

const patch = init([
  // Initialize a `patch` function with the modules used by `toVNode`
  attributesModule // handles attributes from the DOM node
  datasetModule, // handles `data-*` attributes from the DOM node
]);

const newVNode = h("div", { style: { color: "#000" } }, [
  h("h1", "Headline"),
  h("p", "A paragraph"),
  h("img", { attrs: { src: "sunrise.png", alt: "morning sunrise" } })
]);

patch(toVNode(document.querySelector(".container")), newVNode);

Hooks

Hooks are a way to hook into the lifecycle of DOM nodes. Snabbdom offers a rich selection of hooks. Hooks

View on GitHub
GitHub Stars12.4k
CategoryDevelopment
Updated1d ago
Forks1.1k

Languages

TypeScript

Security Score

100/100

Audited on Mar 19, 2026

No findings