Get it

One npm install, or one script tag. No build step either way.

npm
npm install domma-reactive
import {observable, computed, applyBindings} from 'domma-reactive';   // ESM
const {observable} = require('domma-reactive');                       // CommonJS

Works with Vite, webpack, Rollup, esbuild or nothing at all. There is no plugin to configure and no transform to register - it is plain JavaScript that happens to ship three bundles.

A script tag
<script src="https://cdn.jsdelivr.net/npm/domma-reactive@1/dist/domma-reactive.min.js"></script>
<script>
    const count = DommaReactive.observable(0);
</script>

The UMD bundle puts everything on DommaReactive. For a module without a bundler:

<script type="module">
    import {observable} from 'https://cdn.jsdelivr.net/npm/domma-reactive@1/+esm';
</script>

Where it lives

npm

The published package - domma-reactive, currently 1.2.0, MIT, no dependencies.

npmjs.com/package/domma-reactive

GitHub

Source, issues and the full history. Pull requests welcome; the test suite runs on every one.

pinpointzero73/domma-reactive

The documentation

The README is the reference - every binding, every export, and the reasoning behind each decision.

Read the README

Package domma-reactive on npm
Source github.com/pinpointzero73/domma-reactive
Reference The reference on this site, or the README upstream
Setup Complete setup guide - bundlers, Node, CSP, disposal, troubleshooting
Tutorial Tutorial.md - or the same thing running, here
Changelog CHANGELOG.md
Issues github.com/pinpointzero73/domma-reactive/issues
Licence MIT
The wider framework Domma JS - this is its reactive core, published on its own (source)
A CMS built on it Domma CMS - every admin screen binds with domma-reactive
What's new 1.2: safer bindings, object and array literals

What arrives

File Format Size Use it for
dist/domma-reactive.min.js UMD, minified 65 KB, 21 KB gzipped a <script> tag; the browser field
dist/domma-reactive.cjs UMD 65 KB require()
dist/domma-reactive.esm.js ES module, comments intact 336 KB import - your bundler minifies it

33 exports, and nothing else is public:

observable  observableArray  computed  effect  untracked  flushSync  isEqual
applyBindings  compile  annotate  scanBlocks  TemplateCompiler  renderTemplate
registerBinding  unregisterBinding  registerComponent  unregisterComponent
registerExtender  unregisterExtender  registerHelper  unregisterHelper
createRootContext  createChildContext  trackingProxy
parseExpression  evaluateAst  evaluateExpression  compileExpression
expressionDependencies  clearExpressionCache  Computation  Dep  DepMap

The reactive core - observable, computed, effect, expressions, contexts and the renderer - needs no DOM and runs in Node or a worker. Only the compiler functions touch document, and only when you call them.

TypeScript declarations ship in the package (dist/domma-reactive.d.ts) - nothing to install from @types. observable(0) is an Observable<number>, and assigning to a read-only computed is a compile error rather than a runtime warning.

Standalone, or already there

domma-reactive is the reactive core of Domma JS, published on its own. Use it by itself, as above - or, if a page already loads Domma, it is there as M: M.observable, M.computed and M.applyBindings are this library. Domma CMS is built on the same pair, so every admin screen in it is a working example of the bindings on this site.

The thirty-second version

<div id="app">
    <input type="number" data-model="qty.value">
    <p data-bind-text="total.value"></p>
</div>
import {observable, computed, applyBindings} from 'domma-reactive';

const price = observable(10);
const qty   = observable(3);
const total = computed(() => price.value * qty.value);

applyBindings({price, qty, total}, document.querySelector('#app'));

Type in the box; the paragraph follows. Nothing else on the page is touched, because every binding got its own effect and each effect knows exactly what it read.

Full setup guide Reference Build something with it

A note on what this site runs

Every demo here runs the published 1.2.0 bundle, byte for byte - the same dist/domma-reactive.esm.js npm and jsDelivr serve. What's new in 1.2.