# snabby

> Use Snabbdom with template strings

Latest version **7.0.0** (published 2026-06-03) · MIT license · 0 weekly downloads

## Install

```sh
npm install snabby
pnpm add snabby
yarn add snabby
bun add snabby
```

## Health

**Score 55/100 (C)** — status: active.

Positive: esm support; no vulnerabilities; recently updated.

Warnings: low downloads; no types.

## Facts

| | |
|---|---|
| Version | 7.0.0 |
| Published | 2026-06-03 |
| First published | 2017-01-29 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | ESM + CommonJS |
| Node | >=20 |
| Dependencies | 3 |
| Unpacked size | 11.1 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 97 |
| Author | Jamen Marz |
| Maintainers | mreinstein, jamen |

## Links

- npm: https://www.npmjs.com/package/snabby
- Repository: https://github.com/mreinstein/snabby
- Issues: https://github.com/mreinstein/snabby/issues
- npm.io page: https://npm.io/package/snabby

## Dependencies (3)

- [hyperx](https://npm.io/package/hyperx.md) ^3.0.0
- [snabbdom](https://npm.io/package/snabbdom.md) ^3.0.3
- [is-boolean-attribute](https://npm.io/package/is-boolean-attribute.md) ^0.0.1

## Recent versions

- 7.0.0 (latest) — 2026-06-03
- 6.1.1 — 2024-01-17
- 4.2.6 — 2024-01-05
- 5.0.1 — 2024-01-05
- 6.1.0 — 2023-11-02
- 6.0.0 — 2023-10-29
- 5.0.0 — 2022-09-07
- 4.2.5 — 2022-01-01
- 4.2.4 — 2021-06-04
- 4.2.3 — 2021-06-04
- 4.2.2 — 2021-04-08
- 4.2.1 — 2021-03-30
- 4.2.0 — 2021-03-30
- 4.1.2 — 2021-03-29
- 4.1.1 — 2021-03-29
- … 15 more at https://npm.io/package/snabby/versions

## README

# snabby

Use Snabbdom with template strings

![tests](https://github.com/mreinstein/snabby/actions/workflows/main.yml/badge.svg)


```js
import html from 'snabby'

// Create vnodes:
let foo = html`<div>Hello Earth</div>`
let bar = html`<div>Hello Mars</div>`

// Patch to DOM:
html.update(document.body, foo)

// Patch updates:
html.update(foo, bar)
```

Snabby is for creating [Snabbdom](https://github.com/snabbdom/snabbdom) [virtual nodes](https://github.com/snabbdom/snabbdom#virtual-node) using template strings, and also patch the nodes using an [`update` function](#snabby_update) (inspired by [`yo-yo`](https://npmjs.com/yo-yo)).  It makes working with an [amazing virtual dom](https://github.com/snabbdom/snabbdom#features) very easy and fun


## Installation

Snabby version 2.x is a pure es module. It requires node >= v12.17 or a browser that supports the es module format.

If you want the older commonjs build, use the `snabby@1.x` npm module


## Usage

### `snabby`

A [tag function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals) that creates a node.  This function is usually required as `html` instead of `snabby`:

```js
import html from 'snabby'

// Function to create VNode from params:
let greet = name => html`
  <div class='greet'>Hello, ${name}!</div>
`

let node1 = greet('Jamen')
// Hello, Jamen!

let node2 = greet('World')
// Hello, World!
```

You have all the [modules documented by Snabbdom](https://github.com/snabbdom/snabbdom#modules-documentation) loaded by default.  See [Directives](#directives) for how to use modules, and [`snabby/create`](#snabby_create) for loading custom modules


### Directives

Directives are attributes that begin with `@`, and let you interact with Snabbdom modules.  In general, the form is `@<name>:[prop]:...`.

Here is an example using the [`props`](https://github.com/snabbdom/snabbdom#the-props-module) module:

```js
html`<a @props=${{ href: '/foo', textContent: 'Hello' }}></a>`

// Or using the `:prop` syntax:
html`<a @props:href='/foo' @props:textContent='Hello'></a>`
```

For the [`eventlisteners`](https://github.com/snabbdom/snabbdom#eventlisteners-module) module, you can use a shorthand by prefixing with `:` instead of `@on:`:

```js
html`<div @on:click=${fn}>...</div>`

// Shorthand:
html`<div :click=${fn}>`
```

Directives work with any module that makes use of `node.data`.  For example `@props:href` turns into `node.data.props.href`.


### Delayed Style properties

Snabbdom offers [`delayed style properties`](https://github.com/snabbdom/snabbdom#delayed-properties) which are set after the next frame.

This makes it easy to declaratively animate the entry of elements.

The `all` value of `transition-property` is not supported in snabbdom or snabby.

usage:

```javascript
html```<span @style:transition="opacity 1s ease"
             @style:delayed=${ { opacity: '0' } }>
         hello, world!!
       </span>```
```


### `snabby.update(target, node)`

If you want to put a node on the DOM, or push updates on it (i.e. from events), you use this function.

First things first, the Node has to be mounted to the DOM, _before_ you try and update it:

```js
import html from 'snabby'

let visit = location => html`
  <div class='app'>Hello, ${location}!</div>
`

let node1 = visit('Earth')

// Mount node to DOM
html.update(document.body, node1)
// Hello, Earth!
```

From there, you can patch updates:

```js
let node2 = visit('TRAPPIST-1')

// Patch updates to node1
html.update(node1, node2)
// Hello, TRAPPIST-1!
```


### `snabby/create`

Create a `snabby` tag function with your own modules.

Here is an equivalent to `snabby` for example:

```js
import create                   from './create.js'
import { attributesModule }     from 'https://cdn.jsdelivr.net/npm/snabbdom@3/build/package/modules/attributes.js';
import { classModule }          from 'https://cdn.jsdelivr.net/npm/snabbdom@3/build/package/modules/class.js';
import { propsModule }          from 'https://cdn.jsdelivr.net/npm/snabbdom@3/build/package/modules/props.js';
import { styleModule }          from 'https://cdn.jsdelivr.net/npm/snabbdom@3/build/package/modules/style.js';
import { eventListenersModule } from 'https://cdn.jsdelivr.net/npm/snabbdom@3/build/package/modules/eventlisteners.js';


const html = create([
    attributesModule,
    eventListenersModule,
    classModule,
    propsModule,
    styleModule
])

```

As mentioned, you can use directives with 3rd party modules fine.  Open an issue if you can't!


### `snabby.thunk(selector, key, renderFn, [stateArguments])`

The `thunk` function takes a selector, a key for identifying a thunk, a function that returns a vnode and a variable amount of state parameters. If invoked, the render function will receive the state arguments.

The `renderFn` is invoked only if the `renderFn` is changed or `[stateArguments]` array length or it's elements are changed.


```js
function counter (count) {

    function numberView (n) {
        return html`<span>Number is ${n}</span>`
    }

    function rand () {
        const randomInt = Math.ceil(Math.random() * 3)
        html.update(view, counter(randomInt))
    }

    const view = html`
        <div class='main'>
          <span>${html.thunk('num', numberView, [count])}</span>
          <button @on:click=${rand}>random</button>
        </div>`
}

```

This is identical to snabbdom's `thunk` function. See https://github.com/snabbdom/snabbdom#thunks for more details.



## Prior Art

These ideas come from my time using:

 - [`yo-yo`](https://npmjs.com/yo-yo): Inspired some of the API here
 - [`hyperx`](https://npmjs.com/hyperx): Handles the template string parsing here
 - [`choo`](https://npmjs.com/choo): What inspired me to create this module, as I love the API, but not `morphdom` as much
 - [`bel`](https://npmjs.com/bel):  Notable mention.  It's like twin sister to this. DOM and VDOM
 - [`snabbdom`](https://npmjs.com/snabbdom): What gives this the speed
 - [`vue`](https://npmjs.com/vue): A front-end framework that uses `snabbdom` and loosely inspired me


## License

MIT © [Jamen Marz](https://git.io/jamen)

---

[![version](https://img.shields.io/npm/v/snabby.svg?style=flat-square)](https://npmjs.com/package/snabby) [![travis](https://img.shields.io/travis/snabby/jamen.svg?style=flat-square)](https://travis-ci.org/snabby/jamen) [![downloads/month](https://img.shields.io/npm/dm/snabby.svg?style=flat-square)](https://npmjs.com/package/snabby) [![downloads](https://img.shields.io/npm/dt/snabby.svg?style=flat-square)](https://npmjs.com/package/snabby) [![license](https://img.shields.io/npm/l/snabby.svg?style=flat-square)](https://npmjs.com/package/snabby) [![support me](https://img.shields.io/badge/support%20me-paypal-green.svg?style=flat-square)](https://www.paypal.me/jamenmarz/5usd) [![follow](https://img.shields.io/github/followers/jamen.svg?style=social&label=Follow)](https://github.com/jamen)

---
_Source: https://npm.io/package/snabby · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
