Skip to main content

Author cells from Python

Notebook accepts cells from four helpers. Each helper wraps a source string in one Notebook Kit cell mode.

HelperCell source
obs.js(...)Standard Notebook Kit JavaScript
obs.ojs(...)Observable JavaScript
obs.md(...)Markdown
obs.html(...)HTML

Top-level declarations in JavaScript cells form a reactive graph: when a value changes, every cell that references it runs again. Move the exponent control to recompute the readout in the browser.

import marimo as mo
import observablejs as obs

notebook = obs.Notebook(
obs.js(
"""
const exponent = view(Inputs.range(
[1, 8],
{label: "Exponent", step: 1, value: 2}
));
""",
key="exponent_control",
),
obs.js(
'html`<p>Two to the power of ${exponent} is <strong>${2 ** exponent}</strong>.</p>`',
key="readout",
),
)

full_view = notebook.view()
mo.ui.anywidget(full_view)

The first cell defines exponent. The readout references it, so Notebook Kit runs that cell again when the input changes. Notebook Kit schedules cells from their dependencies, independent of source order.

JavaScript cells

An expression cell displays its value implicitly.

obs.js("Plot.lineY(aapl, {x: 'Date', y: 'Close'}).plot()")

A program cell contains declarations or statements. Call display(...) when a program cell should render a value.

obs.js(
"""
const formatter = new Intl.NumberFormat("en-US");
display(formatter.format(42000));
"""
)

view(...) displays an input and defines a reactive value from its events.

obs.js(
'const radius = view(Inputs.range([2, 12], {value: 5, label: "Radius"}));'
)

Observable JavaScript cells

obs.ojs creates a classic Observable JavaScript cell. Use it for existing Observable JavaScript source, viewof declarations, and imported Observable notebook code.

obs.ojs(
'viewof radius = Inputs.range([2, 12], {value: 5, label: "Radius"})'
)

Both cell modes participate in the same Notebook Kit graph.

Markdown and HTML cells

obs.md renders Markdown. obs.html renders HTML.

notebook = obs.Notebook(
obs.md("## Filtered records"),
obs.html("<p><strong>Status:</strong> loaded</p>"),
)

Cell options

Every helper accepts the same options.

obs.js(
"const filtered = [1, 2, 3].filter((value) => value >= 2);",
key="filtered_rows",
display=False,
pinned=True,
)
  • key is the public identity used by notebook.cell("filtered_rows"), notebook.view("filtered_rows"), readback, and graph lookup. It survives Notebook Kit HTML round trips.
  • display=False hides the cell output while keeping its values in the graph.
  • pinned=True exposes the source when the cell is selected and the notebook enables show_pinned_source. See Themes and pinned source.
  • raw=True preserves the source string exactly, including indentation and surrounding newlines.
  • id is Notebook Kit serialization metadata. output and notebookkit_attrs expose mode-specific Notebook Kit metadata.

See Cell helpers for the full signature and error behavior, and Browser execution for the builtins available to each cell.