关于 streamlit-to-marimo
面向开发者和编码 Agent 的技能,将 Streamlit 应用概念映射到 marimo 笔记本模式,涵盖组件、布局、状态、缓存及多页面转换,并指导使用 `uvx marimo check` 检查结果。
主要功能
- 01Streamlit 到 marimo 组件映射
- 02显示元素与布局转换
- 03响应式执行和状态指导
- 04缓存与多页面模式
- 05使用 `uvx marimo check` 验证
适用场景
- 01转换现有 Streamlit 应用
- 02将回调改为响应式单元格
- 03迁移缓存和会话状态
- 04规划多页面笔记本应用
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ marimo-team/ skills --skill streamlit-to-marimo安装后在 Claude Code 中输入/streamlit-to-marimo确认已加载。
详细介绍
将 Streamlit 应用转换为 marimo
有关 marimo 笔记本的一般约定(单元格结构、PEP 723 元数据、输出渲染、marimo check、变量命名等),请参阅 marimo-notebook 技能。本技能专门介绍如何将 Streamlit 概念映射为对应的 marimo 概念。
步骤
-
阅读 Streamlit 应用,了解其控件、布局和状态管理。
-
按照
marimo-notebook技能的约定创建新的 marimo 笔记本。 添加 Streamlit 应用使用的所有依赖项(pandas、plotly、altair 等),但将streamlit替换为marimo。请勿覆盖原文件。 -
使用下方的参考表将 Streamlit 组件映射为对应的 marimo 组件。 主要原则:
- UI 元素会赋值给变量,并通过
.value获取其当前值。 - 用户与 UI 元素交互时,引用该元素的单元格会自动重新运行,无需回调。
- UI 元素会赋值给变量,并通过
-
处理执行模型、状态和缓存方面的概念差异(见下文)。
-
对结果运行
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 字符串: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(最后一个表达式) | 需要交互式 matplotlib 时使用 mo.ui.matplotlib(fig) |
布局
| Streamlit | marimo | 说明 |
|---|---|---|
st.sidebar | mo.sidebar([...]) | 传入元素列表 |
st.columns() | mo.hstack([...]) | 使用 widths=[...] 设置列宽比例 |
st.tabs() | mo.ui.tabs({...}) | 使用 {"Tab Name": content} 字典 |
st.expander() | mo.accordion({...}) | 使用 {"Title": content} 字典 |
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 更进一步,可在多个会话之间将结果持久化到磁盘,适用于模型训练等计算开销较大的任务。
多页面应用
对于 Streamlit 多页面应用,Marimo 提供了两种方案:
- 单个笔记本搭配路由:使用
mo.routes搭配mo.nav_menu或mo.sidebar,在一个笔记本中构建多个“页面”(标签页/路由)。 - 将多个笔记本作为图库:使用
marimo run folder/运行一个笔记本文件夹,以图库形式提供服务并支持导航。
部署
marimo 提供 molab 来托管 marimo 应用,作为 streamlit community cloud 的替代方案。你可以通过 add-molab-badge 技能生成“在 molab 中打开”按钮。
自定义组件
streamlit 支持自定义组件,但这些组件与 marimo 不兼容。你或许可以通过 marimo-anywidget 技能生成等效的 anywidget,但在着手处理之前,请先与用户讨论。