# duet-virtual-dom

> Use a virtual DOM with duet by passing patches from the worker thread to the main thread, and DOM events from the main thread to the worker.

Latest version **2.0.1** (published 2025-08-22) · ISC license · 0 weekly downloads

## Install

```sh
npm install duet-virtual-dom
pnpm add duet-virtual-dom
yarn add duet-virtual-dom
bun add duet-virtual-dom
```

## Health

**Score 25/100 (F)** — status: maintenance-mode.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: stale; low maintenance score.

## Facts

| | |
|---|---|
| Version | 2.0.1 |
| Published | 2025-08-22 |
| First published | 2016-05-26 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 5 |
| Unpacked size | 10.6 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Colin Gourlay |
| Maintainers | colingourlay |

## Links

- npm: https://www.npmjs.com/package/duet-virtual-dom
- Repository: https://codeberg.org/colingourlay/duet-virtual-dom
- Issues: https://codeberg.org/colingourlay/duet-virtual-dom/issues
- npm.io page: https://npm.io/package/duet-virtual-dom

## Dependencies (5)

- [tree-walk](https://npm.io/package/tree-walk.md) ^0.4.0
- [virtual-dom](https://npm.io/package/virtual-dom.md) ^2.1.1
- [duet-channel](https://npm.io/package/duet-channel.md) ^2.0.0
- [form-data-set](https://npm.io/package/form-data-set.md) ^2.0.0
- [vdom-serialized-patch](https://npm.io/package/vdom-serialized-patch.md) ^1.0.8

## Recent versions

- 2.0.1 (latest) — 2025-08-22
- 2.0.0 — 2025-08-22
- 1.1.0 — 2016-09-22
- 1.0.0 — 2016-05-26

## README

# duet-virtual-dom

Use a virtual DOM with [duet](https://codeberg.org/colingourlay/duet) by passing patches from the worker thread to the main thread, and expected DOM events back in.

```
$ npm install duet-virtual-dom
```

## Usage

```javascript
var duet    = require('duet');
var channel = require('duet-virtual-dom/channel');
var vdom    = require('duet-virtual-dom');
var h       = require('virtual-dom/h');

duet([channel], function () {
    var update = vdom('body');

    function view(state) {
        return h('button', {dataset: {click: onClick}}, state);
    }

    function onClick(event, value) {
        render();
    }

    function render() {
        update(view((new Date()).toLocaleTimeString()));
    }

    render();
});
```

## API

### `vdom(selector[, options])`

Creates a virtual dom in the main thread's document inside (or at) the selector provided, returning an `update` method you can call with subsequent virtual dom trees.

* `selector` - used to select an element in the DOM. By default your virtual dom's root will be inserted into it.
* `options` - an optional object which may contain:
    * `tree` - an initial virtal dom tree.
    * `isTarget` - a boolean specifying whether the selector is for an element that should be replaced by your virtual dom, rather than a container your virtual dom will be inserted into.

### `update(tree)`

Call this with a virtual dom tree. The tree will be diffed with the last tree, new event handlers (if any) will be registered, and the resulting patch will be serialised and sent to the main thread and applied.

Any event handlers you specify by name (click, select, etc.) in your virtual dom tree as properties of a node's dataset will be replaced by references, which will be sent back from the main thread when they occur. Your event handler will be called with two arguments:

* `event` - The event object itself (well, all that was fit to serialize), including a `target` property which contains all non-dom-specific data.
* `value` - An object containing the value of the event's target, if it was a named input, or all named child inputs if the event's target was a form element.

## Example

An example can be seen in the [duet example app](https://codeberg.org/colingourlay/duet-example-app).

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