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:
_esmholds 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;elis the DOM element you attach to.count = traitlets.Int(0).tag(sync=True)is what makes the Python attribute and the JavaScriptmodelstay 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.counttracks your clicks, you have a working baseline to swap in your own_esmand 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.