Place notebook results in a view
View source requests notebook results through projection hosts. Choose the host that matches what the frontend needs:
| Result | View source | Use it for |
|---|---|---|
| Complete cell | <marimo-cell name="summary"> | Native controls, output, logs, errors, and reactive behavior |
| Rendered output | <marimo-output value="chart"> | One Python value rendered through marimo's native output system |
| Browser value | <span mo-value="metrics.total"> | JSON-compatible data or an eager dataframe consumed by browser code |
All projection hosts belong inside #app-shell.
Place a complete cell
Name the producing cell in the notebook:
@app.cell
def sport_control(athletes, mo):
sport = mo.ui.dropdown(
options=athletes["sport"].unique().sort().to_list(),
label="Sport",
)
sport
return (sport,)Place the cell by name:
<marimo-cell name="sport_control"></marimo-cell>The host preserves the native control and its complete cell lifecycle. A control change reruns dependent notebook cells and updates their mounted results.
Render one notebook output
Use marimo-output when marimo should choose the native renderer:
<marimo-output value="selected_roster"></marimo-output>The host stores marimo's rendered output in a Prepared export. Use mo-value when browser code should receive the underlying portable value.
Output selectors can traverse attributes, dictionary keys, and list items:
report.chart
results["overview"]
rows[0]Read a browser value
mo-value assigns the current value to host.marimoValue and dispatches an event when the value changes:
<span id="summary-data" hidden mo-value="summary"></span>
<output id="summary-total"></output>
<script type="module">
const host = document.querySelector("#summary-data");
const output = document.querySelector("#summary-total");
const render = (value) => {
output.value = value.total.toLocaleString();
};
host.addEventListener("marimo-value-updated", (event) => {
render(event.detail.value);
});
if (host.marimoValue !== undefined) {
render(host.marimoValue);
}
</script>Register the listener before reading marimoValue. undefined means the value has not arrived or cannot currently be read. JSON null remains a valid value. Listen for marimo-value-error when the view needs a local recovery state.
React starters provide useMarimoValue. Svelte starters provide observeMarimoValue.
Pass a dataframe to JavaScript
An eager dataframe reaches browser code as a Flechette Table. Studio encodes the dataframe as Arrow IPC, a columnar data interchange format, and decodes it before updating the host.
const chartRows = table.select(["region", "revenue"]).toArray();Treat the shared table as immutable. Keep data columnar while selecting fields or passing it to a column-oriented library. Call toArray() at a consumer that needs row objects.
The Browser runtime requires browser-compatible dataframe and Arrow writer packages. Prepared export writes eager dataframes through marimo's cache as Arrow IPC before the static directory is published. Materialize lazy or remote queries in the notebook before projecting them.
Use dynamic projection targets deliberately
React and Svelte providers inspect literal targets and finite arrays during the build. Keep those targets explicit when possible:
{
["summary", "details"].map((name) => <marimo-cell key={name} name={name} />);
}When runtime state can choose any notebook target, declare that broader authorization on the host:
<marimo-cell name={selectedName} data-marimo-allow="*" />data-marimo-allow="*" permits that source location to request any valid target of the same projection kind. Use it at the narrowest dynamic host. A computed target without the declaration fails provider inspection. Prepared export requires finite projection targets and rejects wildcard mounts. Use --runtime wasm when a static view must choose arbitrary targets at runtime.
Name and validate targets
A semantic native cell name is the direct target. Give an anonymous cell a stable alias when renaming it is unsuitable:
marimo-studio notebook bind summary --target analysis.py --cell 12The alias belongs to the notebook and is available to every view.
Validate source and notebook names without executing the notebook:
marimo-studio validate dashboard --target analysis.pyExecute the complete notebook, then check the view's selected projections:
marimo-studio validate dashboard \
--target analysis.py \
--level runtimeRuntime validation can perform file, network, database, and other work from any notebook cell. Use it with trusted notebooks. See the Projection DOM API for event payloads, state attributes, duplicate-host rules, and limits.