streamlit-to-marimo by marimo-team/skills
npx skills add https://github.com/marimo-team/skills --skill streamlit-to-marimo关于 marimo 笔记本的一般约定(单元格结构、PEP 723 元数据、输出渲染、marimo check、变量命名等),请参考 marimo-notebook 技能。本技能专门关注将 Streamlit 概念映射到 marimo 的等效实现。
阅读 Streamlit 应用以理解其小部件、布局和状态管理。
创建一个新的 marimo 笔记本,遵循 marimo-notebook 技能的约定。添加 Streamlit 应用使用的所有依赖项(pandas、plotly、altair 等)——但将 streamlit 替换为 marimo。您不应覆盖原始文件。
使用下面的参考表将 Streamlit 组件映射到 marimo 的等效组件。关键原则:
.value 访问。广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
处理执行模型、状态和缓存方面的概念差异(见下文)。
对结果运行 uvx marimo check 并修复任何问题。
| Streamlit | marimo | 备注 |
|---|---|---|
st.slider() | mo.ui.slider() | |
st.select_slider() | mo.ui.slider(steps=[...]) | 通过 steps 传递离散值 |
st.text_input() | mo.ui.text() | |
st.text_area() | mo.ui.text_area() | |
st.number_input() | mo.ui.number() | |
st.checkbox() | mo.ui.checkbox() | |
st.toggle() | mo.ui.switch() | |
st.radio() | mo.ui.radio() | |
st.selectbox() | mo.ui.dropdown() | |
st.multiselect() | mo.ui.multiselect() | |
st.date_input() | mo.ui.date() | |
st.time_input() | mo.ui.text() | 没有专用的时间小部件 |
st.file_uploader() | mo.ui.file() | 使用 .contents() 读取字节 |
st.color_picker() | mo.ui.text(value="#000000") | 没有专用的颜色选择器 |
st.button() | mo.ui.button() 或 mo.ui.run_button() | 使用 run_button 来触发昂贵的计算 |
st.download_button() | mo.download() | 返回一个下载链接元素 |
st.form() + st.form_submit_button() | mo.ui.form(element) | 包装任何元素,使其值仅在提交时更新 |
| Streamlit | marimo | 备注 |
|---|---|---|
st.write() | mo.md() 或最后一个表达式 | |
st.markdown() | mo.md() | 支持 f-strings:mo.md(f"Value: {x.value}") |
st.latex() | mo.md(r"$...$") | marimo 使用 KaTeX;参见 references/latex.md |
st.code() | mo.md("```python\n...\n```") | |
st.dataframe() | df(最后一个表达式) | DataFrame 本身会渲染为交互式 marimo 小部件;仅在需要无代码转换时使用 mo.ui.dataframe(df) |
st.table() | df(最后一个表达式) | 如果需要行选择,使用 mo.ui.table(df) |
st.metric() | mo.stat() | |
st.json() | mo.json() 或 mo.tree() | mo.tree() 用于交互式可折叠视图 |
st.image() | mo.image() | |
st.audio() | mo.audio() | |
st.video() | mo.video() |
| Streamlit | marimo | 备注 |
|---|---|---|
st.plotly_chart(fig) | fig(最后一个表达式) | 使用 mo.ui.plotly(fig) 进行选择 |
st.altair_chart(chart) | chart(最后一个表达式) | 使用 mo.ui.altair_chart(chart) 进行选择 |
st.pyplot(fig) | fig(最后一个表达式) | 使用 mo.ui.matplotlib(fig) 进行交互式 matplotlib |
| Streamlit | marimo | 备注 |
|---|---|---|
st.sidebar | mo.sidebar([...]) | 传递一个元素列表 |
st.columns() | mo.hstack([...]) | 使用 widths=[...] 设置列宽比例 |
st.tabs() | mo.ui.tabs({...}) | 字典格式:{"标签名称": 内容} |
st.expander() | mo.accordion({...}) | 字典格式:{"标题": 内容} |
st.container() | mo.vstack([...]) | |
st.empty() | mo.output.replace() | |
st.progress() | mo.status.progress_bar() | |
st.spinner() | mo.status.spinner() | 上下文管理器 |
Streamlit 在每次交互时从上到下重新运行整个脚本。Marimo 使用响应式单元格 DAG——只有依赖于已更改变量的单元格才会重新执行。
st.rerun()——响应性是自动的。st.stop()——通过结构化单元格,使下游单元格自然地依赖于上游值。| Streamlit | marimo |
|---|---|
st.session_state["key"] | 单元格之间的常规 Python 变量 |
回调函数 (on_change) | 引用 widget.value 的单元格会自动重新运行 |
st.query_params | mo.query_params |
| Streamlit | marimo |
|---|---|
@st.cache_data | @mo.cache |
@st.cache_resource | @mo.persistent_cache |
@mo.cache 是主要的缓存装饰器——它的工作方式类似于 functools.cache,但能感知 marimo 的响应性。@mo.persistent_cache 更进一步,将会话间的结果持久化到磁盘,适用于模型训练等昂贵计算。
Marimo 为多页面 Streamlit 应用提供了两种方法:
mo.routes 配合 mo.nav_menu 或 mo.sidebar 在一个笔记本内构建多个“页面”(标签/路由)。marimo run folder/ 运行一个笔记本文件夹,将它们作为带导航的画廊提供服务。marimo 提供 molab 来托管 marimo 应用,而不是 streamlit 社区云。您可以通过 add-molab-badge 技能生成一个“在 molab 中打开”的按钮。
streamlit 具有自定义组件的功能。这些与 marimo 不兼容。您也许可以通过 marimo-anywidget 技能生成一个等效的 anywidget,但在进行此操作之前请与用户讨论。
每周安装量
244
代码仓库
GitHub 星标数
77
首次出现
2026年3月4日
安全审计
安装于
claude-code200
codex113
opencode111
gemini-cli108
github-copilot107
kimi-cli106
For general marimo notebook conventions (cell structure, PEP 723 metadata, output rendering, marimo check, variable naming, etc.), refer to the marimo-notebook skill. This skill focuses specifically on mapping Streamlit concepts to marimo equivalents.
Read the Streamlit app to understand its widgets, layout, and state management.
Create a new marimo notebook following the marimo-notebook skill conventions. Add all dependencies the Streamlit app uses (pandas, plotly, altair, etc.) — but replace streamlit with marimo. You should not overwrite the original file.
Map Streamlit components to marimo equivalents using the reference tables below. Key principles:
.value.Handle conceptual differences in execution model, state, and caching (see below).
Runuvx marimo check on the result and fix any issues.
| Streamlit | marimo | Notes |
|---|---|---|
st.slider() | mo.ui.slider() | |
st.select_slider() | mo.ui.slider(steps=[...]) | Pass discrete values via steps |
st.text_input() | mo.ui.text() |
| Streamlit | marimo | Notes |
|---|---|---|
st.write() | mo.md() or last expression | |
st.markdown() | mo.md() | Supports f-strings: mo.md(f"Value: {x.value}") |
st.latex() | mo.md(r"$...$") | marimo uses KaTeX; see |
| Streamlit | marimo | Notes |
|---|---|---|
st.plotly_chart(fig) | fig (last expression) | Use mo.ui.plotly(fig) for selections |
st.altair_chart(chart) | chart (last expression) | Use mo.ui.altair_chart(chart) for selections |
st.pyplot(fig) | (last expression) |
| Streamlit | marimo | Notes |
|---|---|---|
st.sidebar | mo.sidebar([...]) | Pass a list of elements |
st.columns() | mo.hstack([...]) | Use widths=[...] for column ratios |
st.tabs() | mo.ui.tabs({...}) | Dict of |
Streamlit reruns the entire script top-to-bottom on every interaction. Marimo uses a reactive cell DAG — only cells that depend on changed variables re-execute.
st.rerun() — reactivity is automatic.st.stop() — structure cells so downstream cells naturally depend on upstream values.| Streamlit | marimo |
|---|---|
st.session_state["key"] | Regular Python variables between cells |
Callback functions (on_change) | Cells referencing widget.value re-run automatically |
st.query_params | mo.query_params |
| Streamlit | marimo |
|---|---|
@st.cache_data | @mo.cache |
@st.cache_resource | @mo.persistent_cache |
@mo.cache is the primary caching decorator — it works like functools.cache but is aware of marimo's reactivity. @mo.persistent_cache goes further by persisting results to disk across sessions, useful for expensive computations like model training.
Marimo offers two approaches for multi-page Streamlit apps:
mo.routes with mo.nav_menu or mo.sidebar to build multiple "pages" (tabs/routes) inside one notebook.marimo run folder/ to serve them as a gallery with navigation.marimo features molab to host marimo apps instead of the streamlit community cloud. You can generate an "open in molab" button via the add-molab-badge skill.
streamlit has a feature for custom components. These are not compatible with marimo. You might be able to generate an equivalent anywidget via the marimo-anywidget skill but discuss this with the user before working on that.
Weekly Installs
244
Repository
GitHub Stars
77
First Seen
Mar 4, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
claude-code200
codex113
opencode111
gemini-cli108
github-copilot107
kimi-cli106
agent-browser 浏览器自动化工具 - Vercel Labs 命令行网页操作与测试
140,500 周安装
阿里云文档智能DocMind Node.js SDK使用教程:异步提取文档结构、文本和布局
241 周安装
阿里云轻量应用服务器SWAS-OPEN API管理指南:实例、磁盘、快照、镜像、防火墙
241 周安装
阿里云文档API质量评审工具 - 自动化产品文档与OpenAPI评审报告生成
241 周安装
阿里云OSS ossutil 2.0 测试指南:验证AK配置与存储桶操作
241 周安装
AI求职信写作助手 - 个性化定制求职信模板与写作技巧,提升面试成功率
241 周安装
Modal 无服务器 GPU 指南:在云端运行机器学习工作负载,按秒计费,自动扩缩容
241 周安装
st.text_area() | mo.ui.text_area() |
st.number_input() | mo.ui.number() |
st.checkbox() | mo.ui.checkbox() |
st.toggle() | mo.ui.switch() |
st.radio() | mo.ui.radio() |
st.selectbox() | mo.ui.dropdown() |
st.multiselect() | mo.ui.multiselect() |
st.date_input() | mo.ui.date() |
st.time_input() | mo.ui.text() | No dedicated time widget |
st.file_uploader() | mo.ui.file() | Use .contents() to read bytes |
st.color_picker() | mo.ui.text(value="#000000") | No dedicated color picker |
st.button() | mo.ui.button() or mo.ui.run_button() | Use run_button for triggering expensive computations |
st.download_button() | mo.download() | Returns a download link element |
st.form() + st.form_submit_button() | mo.ui.form(element) | Wraps any element so its value only updates on submit |
references/latex.mdst.code() | mo.md("```python\n...\n```") |
st.dataframe() | df (last expression) | DataFrames render as interactive marimo widgets natively; use mo.ui.dataframe(df) only for no-code transformations |
st.table() | df (last expression) | Use mo.ui.table(df) if you need row selection |
st.metric() | mo.stat() |
st.json() | mo.json() or mo.tree() | mo.tree() for interactive collapsible view |
st.image() | mo.image() |
st.audio() | mo.audio() |
st.video() | mo.video() |
figUse mo.ui.matplotlib(fig) for interactive matplotlib |
{"Tab Name": content}st.expander() | mo.accordion({...}) | Dict of {"Title": content} |
st.container() | mo.vstack([...]) |
st.empty() | mo.output.replace() |
st.progress() | mo.status.progress_bar() |
st.spinner() | mo.status.spinner() | Context manager |