There's something really cool (and new!) that I can host on my blog now thanks to wigglystuff, marimo and marimo-mdx. It's notebooks represented as graphs, like this one:
It takes a few seconds to boot the WASM but once loaded you'll see a graph widget that can embed the variables and will automatically figure out the order in which they run.
If you use it, it is similar to a mo.hstack call in marimo but it also tracks the
order in which variables are defined. This let's us leverage marimo's internal
tracking to figure out which variables need to exist before the other ones
to construct the graph.
It uses pyodide/wasm under the hood and there's even a way to get this running
on a static site generated with Python that does not natively use .mdx files.
Generate this yourself
The page starts life as an ordinary marimo notebook. You edit it as a .py
file and let marimo export it to the MDX flavor that marimo-mdx understands:
marimo export md widget_dag.py --flavor mdx -o post.mdx
That .mdx is a marimo-config fence that declares the dependencies, followed
by python marimo cells. To turn it into the interactive page above you need a
tiny Deno script that compiles the .mdx with the
marimo-mdx remark plugin.
// mdx_to_html.ts -- reads .mdx on stdin, writes an HTML fragment on stdout
import { evaluate } from "npm:@mdx-js/mdx@3";
import { remarkMarimo } from "npm:@marimo-team/mdx-marimo/remark";
import { h } from "npm:preact@10";
import * as runtime from "npm:preact@10/jsx-runtime";
import { renderToString } from "npm:preact-render-to-string@6";
const src = await new Response(Deno.stdin.readable).text();
const { default: MDX } = await evaluate(src, { ...runtime, remarkPlugins: [remarkMarimo] });
console.log(renderToString(h(MDX, {})));
As luck would have it, you don't need to install node for this to work. uvx can fetch Deno, and Deno fetches the
npm packages for you.
cat post.mdx | uvx deno run -A --node-modules-dir=auto mdx_to_html.ts > post.html
Finally, for a static Python site, make sure you load the browser runtime once on the page so pyodide hydrates the cells into live widgets:
<link rel="stylesheet" href="https://esm.sh/@marimo-team/mdx-marimo/styles.css">
<script type="module" src="https://esm.sh/@marimo-team/mdx-marimo/element/auto"></script>
And there you go, nested marimo notebook outputs can be hosted on a static markdown site!