What's new in 1.2

Safer bindings, and object and array literals. Released 28 September 2026.

The short version

  • A bare observable fails closed. data-if="show" - the observable, not show.value - used to show its content, because an object is truthy. It now reads as empty and warns once, naming the fix.
  • A nested virtual block fails closed. A <!-- dm if --> inside a virtual list's body used to render in every row; it is now left out, with a warning pointing at {{#if}}.
  • Object and array literals parse. data-bind-style="{color: tone}", ['Low', 'High'][level] and data-params="{a: x}" - still without eval.

Both fixes change behaviour only for markup that was already wrong, and in the safe direction: something that was showing by mistake now stays hidden, with a console line saying why.

The safety demo: a data-if on a bare observable stays hidden, a method call is skipped, a nested virtual if is left out of every row, and a console panel lists the three warnings the library printed
The safety demo - every warning in the console panel is the library's own output, captured as it bound.

An observable is not its value

<p data-if="show">Never shown - and one warning</p>
<p data-if="show.value">Shown when show is true</p>

The warning reads: "show" is an observable, not its value - use "show.value". The same holds for data-bind-hidden, -disabled and -checked (off), for text and attributes (an empty string, never [object Object]), and for an observable used as an operand - !show reads as empty too, so it cannot flip open. There is still no automatic unwrapping: one spelling, .value, everywhere.

Try it on the safety page

Object and array literals

Risk: Medium

An object literal sets three style properties; an array literal indexed by level.value picks the colour and the label.

Keys are names or quoted strings. Computed keys, shorthand, spread, methods, holes and trailing commas are refused with a message giving the position, and __proto__, constructor and prototype are refused as keys - a literal is no way round the read guard. Each evaluation builds a fresh value.

More on expressions

Upgrading

npm install domma-reactive@1.2.0

No API changed and nothing was removed - 33 exports, the same as 1.1. If your console now shows "x" is an observable, not its value, that binding was showing (or enabling) something it should not have been: add .value.

Tests 996 (31 new)
Size 65 KB minified, about 21 KB gzipped
Also The README and tutorial updated throughout; the package homepage is now this site

Also shipped in Domma JS 0.50.1 and Domma CMS 0.101.5, which bundle this release.

Full changelog Get it