Marimo Cheatsheet

Useful patterns for Python notebook library, Marimo.

marimo is a Python interactive notebook framework, similar to Jupyter Notebook and Streamlit.

Marimo compiles each cell into a Python function and represents all cells as nodes in a directed acyclic graph (DAG). When a cell changes, its dependent downstream cells are re-executed automatically, so you never have to hunt for and rerun stale cells as in Jupyter Notebooks. This reactive execution model, similar to modern JavaScript UI frameworks, enables more intuitive and efficient interfaces. If you are deploying your notebook as a prototype app, Marimo certainly beats Streamlit’s linear, full-script rerun approach.

Note

Also check the official user guide and reference.

Arbitrary JavaScript

Often running arbitrary JavaScript on the client side is necessary. For example, recording keyboard events. Iframes don’t always work well. The solution is to create an anywidget and embed JavaScript in there.

Warning

This code doesn’t sanitize its JavaScript script, so you should never pass user written content to it 🙈.

Implementation
import textwrap

import marimo as mo
import anywidget

def Arbitrary(script: str, *, visualize_err: bool = False) -> mo.ui.anywidget:
    """A Marimo component that runs arbitrary JavaScript in the notebook front-end.

    Args:
        script (str): The JavaScript code to run.
        visualize_err (bool, optional): Whether to visualize errors in the front-end. Defaults to False.

    Returns:
        mo.ui.anywidget: The Marimo anywidget component.
    """
    
    script_visualize_err = textwrap.dedent(f"""
        const pre = document.createElement("pre");
        pre.textContent = "An error occured in JavaScript:\\n" + String(error);
        
        // Simulates Marimo error message
        pre.className = "text-sm p-2 border whitespace-pre-wrap overflow-hidden text-error border---red-6 shadow-error bg---red-1 hover:bg---red-3";
        el.replaceChildren(pre);
    """) if visualize_err else ""
    
    script = textwrap.dedent(f"""
        function render({{ el, model }}) {{
            try {{
                {script}
            }} catch (error) {{
                console.error("[ArbitraryWidget]", error);
                
                {script_visualize_err}
            }}
        }}
        export default {{ render }};
    """)

    ArbitraryWidget = type("ArbitraryWidget", (anywidget.AnyWidget,), {
        "_esm": script,
    })

    return mo.ui.anywidget(ArbitraryWidget())

Then you can use it to wrap arbitrary JavaScript execution.

Arbitrary(r"""
  alert("Hello from the frontend!");
""")