marimo-batch — Claude Code skill: what it does, how to install
Prepares marimo notebooks for scheduled batch runs via CLI while preserving interactive UI forms and notebook column layouts.
npx skills add marimo-team/skills --skill marimo-batch -a claude-codeWhat marimo-batch does
This skill refactors a marimo notebook so it executes both interactively and as a headless batch job via uv run. Pydantic models define the job parameters. The notebook reads values from UI sliders during interactive sessions and parses command-line flags with mo.cli_args() when run as a script.
For secret management, the skill introduces python-dotenv and UI-driven EnvConfig validation from wigglystuff. If tracking is required, it adds wandb_project and wandb_run_name to the parameter schema. Column definitions remain untouched. Existing layout structures like @app.cell(column=...) stay intact throughout the edits.
Hyperparameter sweeps use a reference launcher script named grid.py compatible with Hugging Face Jobs, Modal, or RunPod. It runs a dry run by default. Passing --launch submits actual jobs, preventing unintended compute charges before verifying parameter combinations.
What it helps with
- prepare a marimo notebook for unattended batch execution
- parse CLI arguments into a validated Pydantic model
- validate API keys in the marimo UI using EnvConfig
- execute a dry run of hyperparameter combinations before running cloud compute
Example prompts for the agent
- Configure this marimo notebook to run as a CLI batch script with uv run.
- Add Pydantic ModelParams and Weights and Biases logging to my marimo notebook.
- Set up EnvConfig for API keys and expose training parameters to CLI arguments.
How to install marimo-batch
1Skills CLI (Vercel)
npx skills add marimo-team/skills --skill marimo-batch -a claude-code2Manually: put the files in place
~/.claude/skills/marimo-batch/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/marimo-batch/
1Skills CLI (Vercel)
npx skills add marimo-team/skills --skill marimo-batch -a codex2Manually: put the files in place
.agents/skills/marimo-batch/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add marimo-team/skills --skill marimo-batch -a cursor2Manually: put the files in place
.cursor/skills/marimo-batch/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install marimo-team/skills marimo-batch2Manually: put the files in place
.github/skills/marimo-batch/SKILL.md1Skills CLI (Vercel)
npx skills add marimo-team/skills --skill marimo-batch -a gemini-cli2Platform CLI
gemini skills install https://github.com/marimo-team/skills --path skills/marimo-batchManually: put the files in place
.devin/skills/marimo-batch/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add marimo-team/skills --skill marimo-batch -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about marimo-batch
How do I install marimo-batch in Claude Code?
Run npx skills add marimo-team/skills --skill marimo-batch -a claude-code in your terminal.
What does the marimo-batch skill do?
It refactors marimo notebooks to support scheduled and command-line execution alongside interactive UI controls. The skill implements Pydantic-based configuration, handles CLI argument parsing, and preserves existing UI columns.
How does marimo-batch handle hyperparameter sweeps?
It points to a grid.py script that samples configurations matching ModelParams. Running uv run grid.py performs a dry run, while adding --launch dispatches jobs to compute backends like Hugging Face Jobs, Modal, or RunPod.
Source text
SKILL.md · Apache-2.0
---
name: marimo-batch
description: An opintionated skill to prepare a marimo notebook to make it ready for a scheduled run.
---
Pydantic is a great way to declare a source of truth for a batch job, especially for ML. You can declare something like:
```python
from pydantic import BaseModel, Field
class ModelParams(BaseModel):
sample_size: int = Field(
default=1024 * 4, description="Number of training samples per epoch."
)
learning_rate: float = Field(default=0.01, description="Learning rate for the optimizer.")
```
You can fill these model params with two methods too, you can imagine a form in the UI.
```python
el = mo.md("""
{sample_size}
{learning_rate}
""").batch(
sample_size=mo.ui.slider(1024, 1024 * 10, value=1024 * 4, step=1024, label="Sample size"),
learning_rate=mo.ui.slider(0.001, 0.1, value=0.01, step=0.001, label="Learning rate"),
).form()
el
```
But you can also use the CLI from marimo.
```python
if mo.app_meta().mode == "script":
if "help" in mo.cli_args() or len(cli_args) == 0:
print("Usage: uv run git_archaeology.py --repo <url> [--samples <n>]")
print()
for name, field in ModelParams.model_fields.items():
default = f" (default: {field.default})" if field.default is not None else " (required)"
print(f" --{name:12s} {field.description}{default}")
exit()
model_params = ModelParams(
**{k.replace("-", "_"): v for k, v in mo.cli_args().items()
})
else:
model_params = ModelParams(**el.value)
```
The user can now run this from the command line via:
```bash
uv run notebook.py --sample-size 4096 --learning-rate 0.005
```
This is the best of both worlds, you can use the UI to test and iterate, and then use the CLI to run the batch job. Another benefit is that you can run the notebook with settings to make it run quickly to see if there are any bugs in the notebook.
The user wants to be able to run a notebook using this pattern, so make sure you ask the user which parameters they want to make configurable via the CLI and the proceed to make the changes to the notebook. Make sure you verify the changes with the user before making them.
## Weights and Biases
It is possible that the user is interested in adding support for weights and biases. Make sure you confirm if this is the case yes/no. If that is the case, make sure these ModelParams are logged. You also want to make sure that the `wandb_project` and `wandb_run_name` are part of the ModelParams is the user wants to go down this route.
If the user is keen to start a training job for ML, make sure you use [this starting point](references/starting-point.py). Make sure you keep the columns intact in this notebook!
## Environment Variables
You may need to read environment variables for the job. Use python-dotenv to read a .env file if it exists, but also add an `EnvConfig` so users may add keys manually in a ui.
```python
from wigglystuff import EnvConfig
# With validators
config = EnvConfig({
"OPENAI_API_KEY": lambda k: openai.Client(api_key=k).models.list(),
"WANDB_API_KEY": lambda k: wandb.login(key=k, verify=True)
})
# Block until valid, useful in cell that needs the key
config.require_valid()
# Access values
config["OPENAI_API_KEY"]
config.get("OPENAI_API_KEY", "some default")
```
Make sure you add this `EnvConfig` at the top of the notebook.
## Columns
It can be common for larger marimo notebooks to use the columns feature to make it easy to navigate. If that is the case, you must keep these columns intact!
```python
@app.cell(column=0, hide_code=True)
def _(mo):
mo.md(r"""demo""")
```
## Compute platform
When the job is ready to get some serious compute, it is important that we keep good practices in mind. Consider batch sizes for the data set and make sure that there are plenty of logs so the user can spot if issues arise.
## Grid search
When the user wants to run a hyperparameter sweep, point them to [this grid launcher](references/grid.py). It works with the notebook in `references/starting-point.py` out of the box: it samples random combinations from a search space that matches the notebook's `ModelParams` fields and launches each one as a separate job.
By default the script does a dry run (`uv run grid.py`) so the user can inspect the combinations before spending compute. Pass `--launch` to actually submit jobs. The `--count` and `--seed` flags control how many combinations to sample and the RNG seed.
The reference uses Hugging Face Jobs as the compute provider, but this is just one option. The user can swap it out for Modal, RunPod, or any other provider that can run a uv script.
© marimo-team · Apache-2.0 · marimo-team/skills