# Binding.scala: reactive data binding for Scala, on the JVM and in the browser

> Binding.scala is a reactive data binding library for Scala that runs on both the JVM and Scala.js, and its distinctive idea is that the DOM is updated by precise data binding rather than by diffing a virtual tree, with HTML written as a literal that the compiler type checks. The current 12.x line is the library without any UI framework in it, so you now bring your own HTML layer.

**ThoughtWorksInc/Binding.scala** — Reactive data-binding for Scala

- Repository: https://github.com/ThoughtWorksInc/Binding.scala
- Website: https://javadoc.io/page/com.thoughtworks.binding/binding_2.13/latest/com/thoughtworks/binding/index.html
- Stars: 1,572 · Forks: 101
- Language: Scala
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/thoughtworksinc-binding-scala

## A library without a UI, and where the UI went

Binding.scala is a data binding library for Scala, running on both the JVM and Scala.js, and the README is explicit about the current state of the project. It can be used as the basis of UI frameworks, however the latest 12.x does not contain any built-in UI frameworks any more. The guidance is to look at html.scala, a separate project by the same author, for creating reactive HTML UI, and that project is also the successor of the previously built-in `dom` library, whose javadoc link is still in the README. There is a third repository linked for React, Binding.scala and html.scala interoperability, for using existing React components with Binding.scala. So the modern shape of the project is a data binding core with a sibling HTML layer, and the naming in the README still refers to the older arrangement where the UI was part of the library. For a reader, that matters when reading the docs, because the examples in the wiki may assume a `dom` API that is no longer shipped here.

## Var, Vars and the idea of a binding expression

The core abstraction is small and the README's step two introduces it directly. A `Var` represents a bindable variable, and it also implements the `Binding` trait, so a `Var` can be seen as a binding expression as well, and if another expression depends on a `Var`, the value of that expression changes whenever the value of the `Var` changes. A `Vars` represents a sequence of bindable variables and implements the `BindingSeq` trait, with the same property for comprehensions over a `Vars`. The example defines a case class holding two `Var` fields and then creates an empty `Vars` of that type as the data source. The consequence is that the data model is not a plain value that you copy into the view, it is a set of live cells, and every expression derived from them is kept current by the library rather than by your code re-running. This is the piece that makes the design different from a template that re-renders, and the README's comparison table marks lifecycle management for data binding expressions as automatic.

## HTML as a literal, checked by the compiler

The step three example is the one that makes the case, because the return type is a DOM element type and the markup is written as a literal. In Scala 3 you write an `html"""..."""` interpolation and in Scala 2 you annotate a method with `@html`, and in both cases the method returns a `Binding[HTMLTableElement]`.

```scala
case class Contact(name: Var[String], email: Var[String])

val data = Vars.empty[Contact]
```

```scala
def table: Binding[HTMLTableElement] = {
  html"""<table border="1" cellPadding="5">
    <thead>
      <tr>
        <th>Name</th>
        <th>E-mail</th>
      </tr>
    </thead>
    <tbody>
      ${
        for (contact <- data) yield {
          html"""<tr>
            <td>${contact.name.bind}</td>
            <td>${contact.email.bind}</td>
          </tr>"""
        }
      }
    </tbody>
  </table>"""
}
```

The README describes the `html"""..."""` interpolation in Scala 3, or the `@html` annotated method, as representing a reactive XHTML template that supports HTML literal, and the type of the interpolation is a specific subtype of the binding type. The `for` comprehension over `data` is where the reactive part comes in, because the sequence of contacts is itself a binding, and the `.bind` call reads the current value of a `Var` inside the markup. The result is that the markup is not a string that gets assembled at runtime, it is a description that the library turns into DOM updates.

## The build setup, and a typo in the published snippet

Step one of the getting started is the part that trips people up, because the macro annotations need compiler configuration that differs by Scala version. The README's build.sbt snippet sets `scalacOptions` so that Scala 2.13 gets the `-Ymacro-annotations` flag, and adds the paradise compiler plugin for Scala 2.12, then declares the dependency on html.scala with the cross version triple percent syntax. Two observations about that snippet are worth making. The first is that the version check it shows is written with `} if` where a conditional expression needs an `else`, so the published snippet appears to contain a typo that would not compile as printed, which is a good reason to follow the html.scala project documentation rather than copy it verbatim. The second is that the dependency line is on the html project rather than on Binding.scala itself, which reflects the split described earlier, where the UI layer now lives elsewhere. The repository also carries a `.scalafmt.conf`, a `.sbtopts` and a `project/` directory, so formatting and build settings are committed rather than left to each developer.

## How the README positions it against React

There is a comparison table between Binding.scala and ReactJS, and it is the most opinionated part of the documentation. The claim in the prose is that Binding.scala and html.scala have more features and fewer concepts than other reactive web frameworks like ReactJS. The table then argues the differences. Supporting HTML literal is a yes for Binding.scala, while for React it is partially supported, because regular HTML does not compile unless developers manually replace `class` and `for` attributes with `className` and `htmlFor` and manually convert inline styles from CSS syntax to JSON syntax. The algorithm for updating the DOM is described as precise data binding, which is faster than a virtual DOM, against React's virtual DOM differentiation, which requires manually managed `key` attributes for complicated DOM. Lifecycle management for data binding expressions is automatic, and statically type checking is yes even for HTML tags and attributes. The learning curve row is the one worth reading twice, since it claims an always easy curve against a comparison that is easy to start but requires much more effort to understand the corner cases.

## The repository, the publishing setup and the state of the branches

The tree is compact, with a `Binding/` directory holding the library, a `SafeBuffer/` module, a `build.sbt`, a `project/` directory for build settings, and a `LICENSE` for the MIT grant. There is also a `README-zh.md`, so the project maintains a Chinese translation of its own documentation, and a `pubring.asc` alongside a `secret.sbt`, which are the artefacts of a project that signs and publishes its own artifacts. The quality tooling is standard Scala, with a scalafmt configuration and a Scala CI workflow badge, and the API documentation is published to javadoc.io for the 2.13 artifacts, with a Scala index badge for the latest version. On the version history, the default branch is `12.x` and the newest release is v12.2.0 from January 2023, with a v13.0.0-M0 milestone from November 2021 sitting in the same list. So the 13 line was started as a milestone and the 12 line is what people actually use, while the branch itself is still receiving pushes, most recently in June 2026.

## Conclusion

Adopt Binding.scala if you are building a reactive UI in Scala and you want HTML literals that the compiler checks, a data binding model with automatic lifecycle management, and one codebase that runs on the JVM and in the browser through Scala.js. Do not adopt it expecting a complete UI framework, because the 12.x line no longer contains a built-in one, and the README points you to html.scala for reactive HTML and to a separate project for using existing React components with it. Before you start, note the toolchain requirement, since the macro annotations need a compiler flag on Scala 2.13 or the paradise plugin on 2.12, and check the published example snippet in the README, which appears to contain a typo in the version check. The licence is MIT, the default branch is 12.x, the newest release is v12.2.0 from 2023-01-26, and the last push was on 2026-06-14.

## FAQ

### What is Binding.scala and where is its UI layer?

It is a reactive data binding library for Scala, running on both the JVM and Scala.js. The README states that the latest 12.x no longer contains any built-in UI framework, and points to html.scala for reactive HTML, which is also the successor of the previously built-in dom library, plus a separate project for using React components with it.

### What are Var and Vars in Binding.scala?

A `Var` is a bindable variable that also implements the `Binding` trait, and a `Vars` is a sequence of bindable variables implementing `BindingSeq`. Any expression that depends on a `Var` or a `Vars` changes when the underlying value changes, which is how the reactive updates happen without you re-running anything.

### How do I write HTML with Binding.scala?

With an `html"""..."""` interpolation in Scala 3 or an `@html` annotated method in Scala 2, returning a `Binding[HTMLTableElement]`. The interpolation is a reactive XHTML template that supports HTML literal, and the markup is statically type checked, including the tags and attributes.

### What does the build.sbt setup need for Scala 2.13 and 2.12?

Scala 2.13 needs the `-Ymacro-annotations` scalac flag, and Scala 2.12 needs the paradise compiler plugin at version 2.1.1, according to the README's step one snippet. The dependency line shown adds html.scala with the cross version syntax, and the published snippet appears to contain a typo in its version check.

## Sources

- [License: MIT](https://github.com/ThoughtWorksInc/Binding.scala/blob/12.x/LICENSE)
- [Project website](https://javadoc.io/page/com.thoughtworks.binding/binding_2.13/latest/com/thoughtworks/binding/index.html)
- [README](https://github.com/ThoughtWorksInc/Binding.scala/blob/12.x/README.md)
- [Releases](https://github.com/ThoughtWorksInc/Binding.scala/releases)
- [ThoughtWorksInc/Binding.scala on GitHub](https://github.com/ThoughtWorksInc/Binding.scala)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/thoughtworksinc-binding-scala
