docs/guides/outputs.md
The last expression of a cell is its visual output, rendered above the cell. Outputs are included in the "app" or read-only view of the notebook. marimo comes out of the box a number of elements to help you make rich outputs, documented in the API reference.
<div align="center"> <figure> <video autoplay muted loop playsinline width="100%" height="100%" align="center" src="/_static/outputs.webm"> </video> </figure> </div>Markdown is written with the marimo library function [mo.md][marimo.md].
Writing markdown programmatically lets you make dynamic markdown: interpolate
Python values into markdown strings, conditionally render your markdown, and
embed markdown in other objects.
Here's a simple hello world example:
import marimo as mo
name = mo.ui.text(placeholder="Your name here")
mo.md(
f"""
Hi! What's your name?
{name}
"""
)
mo.md(
f"""
Hello, {name.value}!
"""
)
Notice that marimo knows how to render marimo objects in markdown: you can just
embed them in [mo.md()][marimo.md] using an f-string, and marimo will
figure out how to display them!
For other objects, like matplotlib plots, wrap
them in [mo.as_html()][marimo.as_html] to tap into marimo's
media viewer:
mo.md(
f"""
Here's a plot!
{mo.as_html(figure)}
"""
)
marimo automatically renders cells that only use mo.md in a markdown editor
that supports common hotkeys. You can switch between the Markdown and Python
editors by clicking the button in the top right:
Writing LaTeX. The markdown editor supports writing LaTeX. You should typically
use a raw string for markdown with LaTeX, which you can activate by checking the r
box in the bottom-right corner of the markdown editor.
Interpolating Python values. Interpolating Python values requires using an
f-string, which you can activate by checking the f box in the bottom-right
corner of the markdown editor.
Create expandable details with additional context:
/// details | Heads up
Here's some additional context.
///
/// marimo-embed-file filepath: examples/markdown/details.py ///
Highlight text using admonitions:
/// attention | This is important.
Pay attention to this text!
///
/// marimo-embed-file filepath: examples/markdown/admonitions.py ///
Use :emoji: syntax to add emojis; for example, :rocket: creates 🚀.
marimo supports serving static files from a public/ folder located next to your notebook. This is useful for including images or other static assets in your notebook.
To use files from the public folder, create a public directory next to your notebook and reference files using the public/ path prefix:
mo.md(
'''
or

'''
)
For security reasons:
public directory can be accessed../) are blockedThe marimo library also comes with elements for laying out outputs, including
[mo.hstack][marimo.hstack], [mo.vstack][marimo.vstack],
[mo.accordion][marimo.accordion], [mo.ui.tabs][marimo.ui.tabs], [mo.sidebar][marimo.sidebar],
[mo.nav_menu][marimo.nav_menu], [mo.ui.table][marimo.ui.table],
and many more.
Use [mo.status.progress_bar][marimo.status.progress_bar] and
[mo.status.spinner][marimo.status.spinner] to create progress indicators:
# mo.status.progress_bar is similar to TQDM
for i in mo.status.progress_bar(range(10)):
print(i)
marimo comes with functions to display media, including images, audio, video, pdfs, and more. See the API docs for more info.
marimo has built-in formatters for many objects, but sometimes the default
representation isn't useful (e.g., <MyClass at 0x...>). In these cases, use
[mo.inspect()][marimo.inspect] to explore an object's attributes, methods,
and documentation as an output. See the API
docs for more details.
While a cell's output is its last expression, it can at times be helpful
to imperatively add to the output area while a cell is running. marimo
provides utility functions like
[mo.output.append][marimo.output.append] for accomplishing this; see the
API docs for more information.
Console outputs, such as print statements, show up below a cell in the console output area; they are not included in the output area or app view by default.
To include console outputs in the cell output area, use
[mo.redirect_stdout][marimo.redirect_stdout] or
[mo.redirect_stderr][marimo.redirect_stderr]:
with mo.redirect_stdout():
print("Hello, world!")
marimo also includes utility functions for [capturing standard out][marimo.capture_stdout] and [standard error][marimo.capture_stderr] without redirecting them. See the API docs for more.
To create a thread that can reliably communicate outputs to the frontend,
use [mo.Thread][marimo.Thread], which has exactly the same API as
as threading.Thread.
When the cell that spawned a [mo.Thread][marimo.Thread] is invalidated
(re-run, deleted, interrupted, or otherwise errored), the thread's
should_exit property will evaluate to True, at which point it is your
responsibility to clean up your thread. You can retrieve the current
[mo.Thread][marimo.Thread] with [mo.current_thread][marimo.current_thread].
Example.
def target():
import marimo as mo
thread = mo.current_thread()
while not thread.should_exit:
...
If you need to forward outputs from threads spawned by third-party code, try
patching threading.Thread:
import threading
import marimo as mo
threading.Thread = mo.Thread
This however may leak threads, since the patched threads won't know to check the mo.Thread's
should_exit property.