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

wasm-compatibility — скилл для Claude Code: проверка блокнотов marimo

Проверяет, запустится ли блокнот marimo в браузере через WebAssembly, и объясняет, что именно сломается.

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

Что делает wasm-compatibility

Скилл читает файл блокнота marimo и прогоняет три встроенных правила линтера: marimo check <notebook> --select MW --format json. MW001 ловит импорты, которых нет в Pyodide или которые там не работают, MW002 — вызовы вроде os.system() и signal.signal(), MW003 — зависимости из PEP 723, для которых на PyPI нет WASM-совместимого колеса.

Линтер покрывает не всё, поэтому часть проверок скилл делает вручную. Смотрит, есть ли блок # /// script и все ли импортируемые пакеты в dependencies, ищет чтение переменных окружения, абсолютные пути и большие наборы данных в памяти. Отдельно предупреждает про конкурентность: threading.Thread и multiprocessing.Process в WASM работают через кооперативные адаптеры, то есть код исполнится, но строго по одному заданию за раз. Если блокнот рассчитывает на реальное ускорение от параллелизма, это повод переписать логику.

На выходе — вердикт PASS, WARN или FAIL, диагностика линтера как есть, ручные замечания и советы по исправлению. Для пакета без WASM-сборки есть два обходных пути: посчитать результат заранее и закешировать его через cache_cells = true и marimo export html-wasm ... --execute, либо взять слой совместимости, который считает в браузере по-настоящему. Первый не закроет непрерывный диапазон значений, который нельзя перечислить заранее.

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

  • узнать, запустится ли блокнот marimo в playground или в экспортированном WASM HTML
  • найти импорты, которых нет в Pyodide, до публикации блокнота
  • проверить дерево зависимостей PEP 723 на наличие WASM-совместимого колеса
  • отличить код, который в браузере исполнится последовательно, от настоящего параллелизма
  • выбрать между предварительным кешированием результата и слоем совместимости

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

  • проверь блокнот analysis.py на совместимость с WASM
  • прогони wasm-compatibility для notebook.py и покажи отчёт
  • почему мой блокнот падает в marimo playground — проверь на WASM

Как установить wasm-compatibility

1Через Skills CLI (Vercel)

npx skills add marimo-team/skills --skill wasm-compatibility -a claude-code

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

~/.claude/skills/wasm-compatibility/SKILL.md

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

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

Вопросы о wasm-compatibility

Как установить wasm-compatibility в Claude?

Выполните npx skills add marimo-team/skills --skill wasm-compatibility -a claude-code. После этого файл скилла лежит в ~/.claude/skills/wasm-compatibility/SKILL.md.

Что делает wasm-compatibility?

Проверяет блокнот marimo на совместимость с WebAssembly и выдаёт отчёт с вердиктом PASS, WARN или FAIL. Сначала запускает правила линтера MW001–MW003, потом добирает то, что статический анализ не видит.

Что скилл проверяет вручную?

Наличие блока # /// script и полноту dependencies, чтение переменных окружения, абсолютные пути, объём данных в памяти. Ещё смотрит, есть ли cache_cells = true — от этого зависит, можно ли пользоваться пакетом, исключённым маркером sys_platform != 'emscripten'.

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

SKILL.md · Apache-2.0
---
name: wasm-compatibility
description: Check if a marimo notebook is compatible with WebAssembly (WASM) and report any issues.
---

# WASM Compatibility Checker for marimo Notebooks

Check whether a marimo notebook can run in a WebAssembly (WASM) environment — the marimo playground, community cloud, or exported WASM HTML.

## Instructions

### 1. Read the notebook

Read the target notebook file. If the user doesn't specify one, ask which notebook to check.

### 2. Run marimo's WASM lint rules

marimo ships three lint rules that catch most WASM incompatibilities automatically. Run them first, and build the report from their output instead of re-deriving these checks by hand:

```bash
marimo check <notebook> --select MW --format json
```

- **MW001** `incompatible-import` — stdlib modules missing or non-functional in Pyodide (`subprocess`, `pdb`, `dbm`, `resource`, `fcntl`, `termios`, `readline`, `curses`, `tkinter`, `pydecimal`, `test`), plus multiprocessing exports and submodules that need native synchronization, shared memory, pipes, or process forking (`Lock`, `Condition`, `Semaphore`, `Barrier`, `Manager`, `Pipe`, `RLock`, `shared_memory`, `ForkContext`/`ForkProcess`, `ThreadPool`, and others). `Process`, `Queue`, `SimpleQueue`, `Pool`, and `ProcessPoolExecutor` stay allowed — they run on WASM-compatible cooperative adapters (see step 3).
- **MW002** `unsafe-system-call` — calls such as `os.system()`, `os.fork()`, `signal.signal()`, `breakpoint()` that fail in Pyodide even when the import itself succeeds.
- **MW003** `incompatible-package` — resolves the notebook's PEP 723 dependency tree (skipping anything excluded by a `sys_platform != 'emscripten'` marker) and checks PyPI for a WASM-compatible wheel, catching cases like `jaxlib` pulled in transitively through `jax`.

**Caveat:** MW001 flags import statements (`from multiprocessing import Lock`, `import multiprocessing.synchronize`), not later attribute access. A bare `import multiprocessing` followed by `multiprocessing.Lock()` deeper in the code can slip through. For notebooks with concurrency code, skim for this by hand too.

**Caveat:** a clean MW003 result does not by itself mean a package is safe to use in the browser. If a notebook marks a package `sys_platform != 'emscripten'`, MW003 skips it entirely — that only tells you the package will not be *installed* in WASM, not that the notebook is free to use it. Check whether the notebook also has `cache_cells = true` and was exported with `--execute` (see step 4). If so, the excluded package can still be used, through caching. If not, any code path that imports or touches the excluded package will fail in the browser, and MW003 will not have warned about it.

### 3. Check what the linter does not cover

These stay manual, agent-driven checks:

- **PEP 723 metadata.** If the notebook has no `# /// script` block, or imports a package that is not listed in `dependencies`, WARN. Without that metadata, packages do not auto-install when the notebook starts in WASM. Version pins and lower bounds are fine — marimo strips version constraints when running in WASM.
- **Runtime-only patterns.** Static lint does not catch these: reading environment variables (`os.environ`, `os.getenv`), hard-coded absolute file paths or `Path.home()`/`Path.cwd()` expecting a real filesystem, and large in-memory datasets (WASM notebooks are capped at 2GB). Flag these where you see them.
- **Concurrency semantics.** WASM notebooks run cooperative adapters for `threading.Thread`, `Event`, `local`, `ThreadPoolExecutor`, `wait`, `as_completed`, and process-shaped `multiprocessing.Process`, `Queue`, `SimpleQueue`, `Pool`, `ProcessPoolExecutor`. The API shape is real, but there are no OS threads, no shared memory, and no true parallelism. Everything runs one task at a time in the single Pyodide interpreter. If the notebook relies on actual concurrent speedup rather than the API shape alone, warn that it runs correctly but sequentially.
- **Cached execution already in place.** Check the notebook's `pyproject.toml` (or inline `# /// script` block) for `[tool.marimo.runtime] cache_cells = true`. If it is set, an incompatible package marked `sys_platform != 'emscripten'` is not automatically a FAIL — see the escape hatches in step 4.

### 4. Produce the report

Output a clear, actionable report:

**Compatibility: PASS / FAIL / WARN**

- **PASS** — the lint check and step 3 both found nothing.
- **WARN** — nothing failed, but step 3 turned up something worth a second look (missing PEP 723 metadata, a runtime-only pattern, or concurrency that will run but not in parallel).
- **FAIL** — the lint check reported a diagnostic, or step 3 found something that will not run at all.

**Lint findings** — paste the diagnostics from step 2 verbatim (file, line, code, message).

**Manual findings** — list anything from step 3, with the cell or line and a suggested fix.

**Recommendations** — for FAIL/WARN notebooks, suggest concrete fixes:
- Replace an incompatible package with a WASM-friendly alternative
- Rewrite an incompatible code pattern

For a package with no WASM build, there is no drop-in replacement. Two escape hatches exist, and they solve different problems — check which one the notebook actually needs:

1. **Precompute every reachable result and cache it.** Exclude the package from WASM with a `sys_platform != 'emscripten'` marker. marimo then runs the real computation once, server-side, and bundles the result into the export:

   ```toml
   # /// script
   # dependencies = [
   #     "marimo",
   #     "torch; sys_platform != 'emscripten'",
   # ]
   #
   # [tool.marimo.runtime]
   # cache_cells = true
   # ///
   ```

   ```bash
   marimo export html-wasm notebook.py -o output_dir --execute
   ```

   This covers a single static result (a plot, a one-off computation) directly. For a small, enumerable set of results — a dropdown or slider over a fixed list of options — decorate the computation with `@mo.persistent_cache(method="lazy")` instead. Add a cell that calls it once for every option before export. See [caching precomputed values](https://docs.marimo.io/guides/exporting/webassembly_html/#precomputed-values). Either way, the excluded package never runs in the browser — the notebook only reads its cached result.
2. **Use a compatibility layer that runs the real computation in the browser.** Precomputing does not cover an input space that cannot be enumerated ahead of time — a slider driving live inference over a continuous range, for example. The notebook needs an actual WASM-native implementation of the computation here. [`moutils.onnx.OnnxRuntime`](https://github.com/marimo-team/moutils/commit/a3a6651bd400429ddb416351aaec54b97535a069) is one example of this pattern: it converts a PyTorch or JAX model to ONNX, and the object it returns runs inference with `onnxruntime-web` in the browser instead of the original framework.

## Additional context

- WASM notebooks run via [Pyodide](https://pyodide.org) in the browser
- Memory is capped at 2GB
- Network requests work but may need CORS-compatible endpoints
- Chrome has the best WASM performance; Firefox, Edge, Safari also supported
- `micropip` can install any pure-Python wheel from PyPI at runtime
- For the full list of marimo's WASM lint rules, see the [lint rules reference](https://docs.marimo.io/guides/lint_rules/#-wasm-rules)
- For a hand-maintained snapshot of Pyodide's built-in packages, see [pyodide-packages.md](references/pyodide-packages.md). It is a quick human-readable reference, but `marimo check --select MW003` queries PyPI directly and stays current automatically

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

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

Всё по теме «ИИ и ML» →
wasm-gallery ruvnet Скилл для поиска, установки и публикации WASM-агентов из общего каталога. Пригодится, когда нужен готовый агент или хочешь поделиться своим. CX Codex +1 741установок wasm-agent ruvnet Запускает изолированных субагентов внутри WebAssembly для безопасного выполнения непроверенного кода без доступа к файловой системе хоста. CX Codex +1 739установок wasm-emscripten mohitmishra786 Скилл ведёт агента через сборку C и C++ в WebAssembly: подбор флагов emcc, экспорт функций, модель памяти, Asyncify и отладка .wasm. CX Codex +1 513установок marimo-pair marimo-team Скилл подключает агента к запущенному блокноту marimo, позволяя проверять переменные ядра и безопасно вносить правки в сессию. CX Codex +1 12 700установок setup-python-tools cognitedata Ставит клиентское выполнение Python-инструментов через Pyodide в приложение с уже готовым useAtlasChat. Нужен, когда агент отдаёт код инструмента, а считать он должен в браузере. CX Codex +1 1 900установок jupyter-notebooks официальный Pierce Boggan Плагин открывает Jupyter-ноутбуки в интерактивном холсте GitHub Copilot: создавать, править, запускать, сохранять и ставить чекпоинты. ★ 40 418звёзд репо

Из того же набора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установок implement-paper Помогает разобрать research paper по шагам и собрать по нему интерактивный marimo-ноутбук вместе с агентом. CX Codex +1 2 700установок streamlit-to-marimo Переводит приложение на Streamlit в ноутбук marimo: разбирает виджеты, состояние и кэш, собирает новый файл и проверяет его. CX Codex +1 2 300установок add-molab-badge Вставляет бейджи «Open in molab» со ссылками на блокноты marimo в файлы Markdown или HTML. Помогает быстро обновить README и документацию. CX Codex +1 2 200установок

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

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