Where to Find anywidget Getting Started Examples

Updated

The fastest starting point is the official anywidget site itself: it shows the install command (pip install anywidget), a complete minimal widget file, and how that widget is used inside a notebook. If you want a conceptual companion to the code, the site also points to a SciPy 2024 talk titled "Beyond Frameworks, a Widget Standard," which explains how anywidget positions itself as a portable widget standard while staying compatible with the existing Jupyter ecosystem.

The official example, end to end

The site's example is a counter widget split across two places: a Python module and a notebook cell.

1. Install

pip install anywidget

2. Define the widget in mywidget/__init__.py

import anywidget
import traitlets

class CounterWidget(anywidget.AnyWidget):
    _esm = """
    function render({ model, el }) {
      let count = () => model.get("count");
      let btn = document.createElement("button");
      btn.innerHTML = `count is ${count()}`;
      btn.addEventListener("click", () => {
        model.set("count", count() + 1);
        model.save_changes();
      });
      model.on("change:count", () => {
        btn.innerHTML = `count is ${count()}`;
      });
      el.appendChild(btn);
    }
    export default { render };
    """
    count = traitlets.Int(0).tag(sync=True)

Three things are worth noticing in this structure:

  • _esm holds the JavaScript as a string, so the widget ships as a single Python file rather than a separate front-end build.
  • render({ model, el }) is the entry point anywidget calls; el is the DOM element you attach to.
  • count = traitlets.Int(0).tag(sync=True) is what makes the Python attribute and the JavaScript model stay in step.

3. Use it in a notebook

from mywidget import CounterWidget

counter = CounterWidget()
counter

Then read or write the synced state directly:

counter.count

The site's example runs at a local notebook server (the page shows a localhost:8888/Demo.ipynb path), so the expected result is a rendered button in the output cell whose label updates as you click, with counter.count reflecting the same value in Python.

What each piece is doing

Piece Role
pip install anywidget Installs the package that provides AnyWidget
_esm The ES module string containing your render function
render({ model, el }) Called to draw the widget into el
model.get / model.set Read and write synced state from JavaScript
model.save_changes() Pushes a JavaScript-side change back to Python
model.on("change:count", ...) Reacts when Python-side state changes
traitlets.Int(0).tag(sync=True) Declares the Python trait that is synced

Where to go next

  • The official site is the primary reference for the install command and the counter example above.
  • The SciPy 2024 talk, "Beyond Frameworks, a Widget Standard," is the site's pointer for understanding how anywidget relates to existing widget frameworks and the wider Jupyter ecosystem — useful if you already know other widget libraries and want to know where anywidget fits.
  • Your own notebook is the verification step: once the counter renders and counter.count tracks your clicks, you have a working baseline to swap in your own _esm and traits.

A practical next task: copy the counter into a module of your own, rename the trait, and confirm that changing it from Python updates the button label — that exercises the sync path in both directions before you build anything more complex.