К основному содержанию
скилл CX Codex

streamlit-to-marimo — скилл для Claude Code: перенос приложения

Переводит приложение на Streamlit в ноутбук marimo: разбирает виджеты, состояние и кэш, собирает новый файл и проверяет его.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add marimo-team/skills --skill streamlit-to-marimo -a claude-code
Открыть на GitHub

Что делает streamlit-to-marimo

Скилл читает исходное приложение Streamlit, смотрит, какие в нём виджеты, раскладка и работа с состоянием, и создаёт рядом новый ноутбук marimo. Оригинальный файл не перезаписывается. Зависимости вроде pandas, plotly и altair переносятся, а streamlit заменяется на marimo.

Внутри — таблицы соответствий по компонентам. st.slider() становится mo.ui.slider(), st.selectbox() — mo.ui.dropdown(), st.dataframe() достаточно вернуть последним выражением ячейки. Виджет присваивается переменной, текущее значение берётся через .value, а ячейки, которые на неё ссылаются, перезапускаются сами. Колбэки и st.rerun() не нужны: у marimo реактивный граф ячеек. Кэш переезжает с @st.cache_data на @mo.cache, а @st.cache_resource — на @mo.persistent_cache.

Отдельно разбираются места, где перенос не механический. Кастомные компоненты Streamlit с marimo несовместимы, и скилл советует сначала обсудить с вами замену на anywidget. Для мультистраничных приложений есть два пути: маршруты внутри одного ноутбука или папка ноутбуков, которую отдаёт marimo run folder/. В конце скилл запускает uvx marimo check и правит найденное, так что для этого шага нужен uv.

Какие задачи решает

  • перенести приложение Streamlit в ноутбук marimo без ручной переписки виджетов
  • заменить колбэки и st.rerun() на реактивные ячейки
  • перевести кэш с @st.cache_data и @st.cache_resource на декораторы marimo
  • разложить мультистраничное приложение по маршрутам или папке ноутбуков
  • проверить готовый ноутбук через uvx marimo check

Примеры запросов агенту

  • Переведи app.py со Streamlit в ноутбук marimo, оригинал не трогай
  • Замени в этом приложении виджеты и кэш на аналоги marimo и прогони uvx marimo check
  • У меня мультистраничное приложение Streamlit — покажи, как собрать то же самое в одном ноутбуке marimo

Как установить streamlit-to-marimo

1Через Skills CLI (Vercel)

npx skills add marimo-team/skills --skill streamlit-to-marimo -a claude-code

2Вручную: положить файлы

~/.claude/skills/streamlit-to-marimo/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/streamlit-to-marimo/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о streamlit-to-marimo

Как установить streamlit-to-marimo в Claude?

Выполните npx skills add marimo-team/skills --skill streamlit-to-marimo -a claude-code. Скилл окажется в ~/.claude/skills/streamlit-to-marimo/SKILL.md.

Что делает streamlit-to-marimo?

Создаёт новый ноутбук marimo по коду приложения Streamlit: переносит виджеты, раскладку, состояние и кэш, затем проверяет результат через uvx marimo check.

Кастомные компоненты Streamlit переносятся?

Нет, они с marimo несовместимы. Скилл предлагает обсудить замену на anywidget, прежде чем что-то делать.

Исходный текст

SKILL.md · Apache-2.0
---
name: streamlit-to-marimo
description: Convert a Streamlit app to a marimo notebook
---

# Converting Streamlit Apps to Marimo

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**.

## Steps

1. **Read the Streamlit app** to understand its widgets, layout, and state management.

2. **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. 

3. **Map Streamlit components to marimo equivalents** using the reference tables below. Key principles:
   - UI elements are **assigned to variables** and their current value is accessed via `.value`.
   - Cells that reference a UI element automatically re-run when the user interacts with it — no callbacks needed.

4. **Handle conceptual differences** in execution model, state, and caching (see below).

5. **Run `uvx marimo check`** on the result and fix any issues.

## Widget Mapping Reference

### Input Widgets

| 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()` | |
| `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 |

### Display Elements

| 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 `references/latex.md` |
| `st.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()` | |

### Charts

| 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)` | `fig` (last expression) | Use `mo.ui.matplotlib(fig)` for interactive matplotlib |

### Layout

| 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 `{"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 |

## Key Conceptual Differences

### Execution Model

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.

- No need for `st.rerun()` — reactivity is automatic.
- No need for `st.stop()` — structure cells so downstream cells naturally depend on upstream values.

### State Management

| 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` |

### Caching

| Streamlit | marimo |
|-----------|--------|
| `@st.cache_data` | `@mo.cache` | Caches based on function arguments; marimo-aware |
| `@st.cache_resource` | `@mo.persistent_cache` | Persists across notebook restarts (serializes to disk) |

`@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.

### Multi-Page Apps

Marimo offers two approaches for multi-page Streamlit apps:

- **Single notebook with routing**: Use `mo.routes` with `mo.nav_menu` or `mo.sidebar` to build multiple "pages" (tabs/routes) inside one notebook.
- **Multiple notebooks as a gallery**: Run a folder of notebooks with `marimo run folder/` to serve them as a gallery with navigation.

### Deploying 

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. 

### Custom components 

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. 

© marimo-team · Apache-2.0 · marimo-team/skills

Похожие скиллы

Все скиллы по теме «Языки программирования» →
marimo-pair marimo-team Скилл подключает агента к запущенному блокноту marimo, позволяя проверять переменные ядра и безопасно вносить правки в сессию. CX Codex +1 12 700установок retro-marimo-pair marimo-team Скилл проводит ретроспективу сессии работы с marimo: находит места, где что-то пошло не так, и превращает их в задачи для команды. CX Codex +1 4 600установок streamlit sanjeed5 Правило для Cursor задаёт, как писать приложения на Streamlit: кэшировать тяжёлые операции, держать UI отдельно от логики и разбивать проект на модули. ★ 3 579звёзд репо debugging-streamlit streamlit Скилл запускает отладку приложений и компонентов Streamlit через команду make debug с горячей перезагрузкой, сбором логов и скриншотами через Playwright. CX Codex +1 493установок jupyter-notebook официальный openai Создаёт чистые Jupyter-ноутбуки для экспериментов и пошаговых руководств через готовые шаблоны и вспомогательный скрипт. Помогает избежать ручной сборки сырого JSON. CX Codex +1 5 600установок harvard-artifacts-collection-etl-analytics reason-machines Скилл для сборки ETL-пайплайна и аналитического дашборда на данных Harvard Art Museums API: Python, SQL и Streamlit. CX Codex +1 1 900установок

Из того же набора8

marimo-notebook Скилл обучает агента создавать реактивные Python-ноутбуки marimo со спецификацией PEP 723 и режимом запуска через CLI. CX Codex +1 5 900установок anywidget-generator Скилл помогает агенту писать кастомные anywidget-компоненты для ноутбуков marimo: JavaScript в _esm, стили в _css, обёртка через mo.ui.anywidget. CX Codex +1 3 600установок marimo-batch Скилл переводит блокноты marimo в режим пакетного запуска через CLI и планировщик. Он добавляет типизацию параметров на Pydantic и сохраняет работу в веб-интерфейсе. CX Codex +1 3 700установок jupyter-to-marimo Инструктирует агента конвертировать блокноты Jupyter .ipynb в реактивные скрипты marimo .py и адаптировать их структуру под граф зависимостей. CX Codex +1 3 400установок wasm-compatibility Проверяет, запустится ли блокнот marimo в браузере через WebAssembly, и объясняет, что именно сломается. CX Codex +1 3 000установок implement-paper Помогает разобрать research paper по шагам и собрать по нему интерактивный marimo-ноутбук вместе с агентом. CX Codex +1 2 700установок add-molab-badge Вставляет бейджи «Open in molab» со ссылками на блокноты marimo в файлы Markdown или HTML. Помогает быстро обновить README и документацию. CX Codex +1 2 200установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой