Skip to content

Commit 711d6ea

Browse files
✨ AnyWidget post (#62)
Co-authored-by: Chris Holdgraf <choldgraf@gmail.com>
1 parent 03036b8 commit 711d6ea

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
title: The MyST AnyWidget Directive
3+
date: 2026-03-05
4+
authors:
5+
- id: stevejpurves
6+
- id: agoose77
7+
- id: choldgraf
8+
---
9+
10+
Authors of MyST Markdown can now embed interactive JavaScript widgets directly in content using the new `{anywidget}` directive.
11+
12+
## What this means
13+
14+
You can now add any javascript interactivity to your MyST Markdown website or Jupyter Book.
15+
16+
Here's an example that creates a clickable button:
17+
18+
```{anywidget} https://github.com/jupyter-book/example-js-anywidget/releases/latest/download/widget.mjs
19+
20+
```
21+
22+
+++
23+
24+
And here's the directive that created it:
25+
26+
::::{code-block}
27+
:caption: This directive has no parameters, so is very simple, pointing to [an ESM module](https://github.com/jupyter-book/example-js-anywidget/releases/latest/download/widget.mjs) that just wraps the [confetti.js](https://confettijs.org/) library 🎉.
28+
29+
```{anywidget} https://github.com/jupyter-book/example-js-anywidget/releases/latest/download/widget.mjs
30+
```
31+
::::
32+
33+
## How we got here
34+
35+
The idea of a portable widget interface for interactive computing isn't new: [anywidget](https://anywidget.dev/) has been an emerging standard in the Jupyter community for a while, leveraging modern Javascript principles (via [ESM Modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules)), and giving you a simple `initialize({ model }); render({ model, el })`[^model] contract so that widgets can be written once and reused across notebooks. AnyWidget in Jupyter interfaces supports tight integration with the kernel, allowing interactions similar to `ipywidgets`[^jupyter].
36+
37+
[^model]: The AnyWidget spec provides for a model that is both responsible for exposing the properties supplied within the `{anywidget}` directive and enables communication between widgets on the page at runtime.
38+
39+
[^jupyter]: See the [Modern Web Meets Jupyter](https://anywidget.dev/blog/anywidget-02/) blog post for an introduction on how AnyWidgets are used in Jupyter
40+
41+
From the MyST Markdown and Jupyter Book point of view, we've focussed on supporting the `render()` side of the AnyWidget interface (see [AnyWidget Frontend Modules](https://anywidget.dev/en/afm/#what-is-afm)) to allow MyST users to bring any kind of javascript-based interactivity into their articles and books _without having to lean on Jupyter at all_.
42+
43+
That part of the story started at SciPy 2024 with [Trevor Mantz](https://github.com/manzt) and Steve Purves hacking through a proof of concept during the sprints. Curvenote built working support for [AnyWidgets as a MyST Markdown extension](https://www.npmjs.com/package/@curvenote/any-widget) while working with researchers to support domain specific visualizations, and then upstreamed the implementation to create the `{anywidget}` directive that has just been released in `mystmd` and `jb2`.
44+
45+
The new directive in `mystmd` and the respective supporting package in `@myst-theme/anywidget` evolved with input from the JupyterBook team. Here's how it is currently structured:
46+
47+
* `anywidget` is a new node in the MyST AST, meaning first-class support for this capability outside of notebooks.
48+
* `mystmd` will bundle ESM and CSS modules at **build time**, ensuring dependencies are packaged with the book/article when it is published or deployed.
49+
* The ESM and CSS modules can either be (a) hosted remotely (which makes sense for shared widgets that many people are using or collaborating around) or (b) added as local files (which makes sense for widgets specific to a single book/website).
50+
* The `NodeRenderer` part of the release is an independent package [@myst-theme/anywidget](https://www.npmjs.com/package/@myst-theme/anywidget) that can be optionally adopted by theme developers (it's already built into the core themes).
51+
* For `mystmd` and Jupyter Book users, to upgrade to the latest theme. Run `myst clean --templates` before you next start your server and the latest version will be downloaded.
52+
53+
## Usage
54+
55+
From an author's perspective, point the directive at an ESM module (either a URL to a hosted script or a local path) and the widget runs in the page with its own state and DOM. You may optionally pass in a CSS URL/path and a JSON body of props to initialize the widget model.
56+
57+
To understand how to build your own widgets, the [MyST widgets guide](https://mystmd.org/guide/widgets) walks through the `render({ model, el })` signature, styling with Shadow DOM, and cleanup on unmount. It's the same mental model as `anywidget` in Jupyter, so if you've written or seen Jupyter AnyWidgets, you're already most of the way there.
58+
59+
If you want to try it, the [example-widgets repo](https://github.com/jupyter-book/example-widgets) has small demos (confetti, div-map, etc. Contributions are welcome!), and the [opensci.dev blog](https://opensci.dev) has some live examples using scientific datasets.
60+
61+
## What's next
62+
63+
Widget support in MyST is still marked experimental so the details may evolve. There are still some things on the roadmap for `{anywidget}` which will no doubt expand as we hear of new requirements from widget creators, but we expect the following to be close to the top of the stack:
64+
65+
* The `model` part of the interface, which will allow multiple instances of a widget to communicate on the page[^model]
66+
* Shipping additional dependencies like static files that the widgets may need
67+
68+
The JupyterBook team is actively working on improving and evolving the widget model and integrating with Jupyter. We look forward to seeing what the community builds — visit the [discord](https://discord.mystmd.org/) to showcase what you have built!

0 commit comments

Comments
 (0)