The Anthropic Cookbook is an excellent resource for learning how to write LLM code and it’s continually being updated, most recently with example code for agents.

The Cookbook comes as a set of Jupyter notebooks. I prefer Marimo to Jupyter, mainly because it supports reactive cell reloading i.e. if you change an earlier notebook cell that a later cell depends on, the chain of dependencies is calculated and everything is re-run correctly which saves a lot of mental energy and stupid mistakes when working with notebooks.

So this post is a quick set of notes on getting up and running with Marimo and converting the Cookbook to work with it.

Marimo Setup

For our setup, we’re going to install everything into virtualenvs managed by uv. This keeps everything organized, but you’ll need to repeat these steps to set up additional clean Marimo environments

First, let’s get Marimo up and running. I prefer to not work directly in the anthropic-cookbook repo but to copy out files as needed. I’ll explain why later.

$ brew install uv
$ mkdir anthropic-experiments
$ cd anthropic-experiments
$ uv venv
$ source .venv/bin/activate
$ uv init
$ uv add pip
$ rehash
$ uv add marimo
$ uv add "marimo[recommended]"
$ uv add "marimo[lsp]"
$ uv add mypy
$ marimo edit

This should launch a browser window.

Next we’ll do some basic config. Most everything can be done via the browser but the config is stored in a toml file. Use marimo config show to display the file’s location and contents if needed. Usually it’s ~/.config/marimo/marimo.toml

Go into settings:

  1. Set Runtime > On Cell Change to lazy to avoid automatic recomputation of cells. Since running a cell can cost real money, we want this to be more controlled. See the docs on expensive notebooks for more

  2. Configure LLM API keys in settings under ‘AI’. This is solely for the AI assistant within the notebook and is optional. The only settings you need here are to enter your Anthropic API key and choose the model. I suggest Sonnet-4. Of course you can use an OpenAI key and o4-mini or whatever here equally well. There’s no need to set the API endpoint.

You can test this by creating a new notebook and selecting “Generate with AI”. Try “write fizzbuzz”. On first run it’ll prompt you to install the Anthropic library

Marimo dependency install dialogue

Marimo will give this same prompt anytime your code includes a new dependency, which makes it very easy to add libraries. The only gotcha is that the notebook stop executing the cell once interrupted by a package install. You’ll need to press play again. So press play and you should have some amazing fizzbuzz code. Press play again to run it.

Finally, you may want to enable some extra features. Each of these will automatically download dependencies in the same way

Marimo extra features install dialogue

Let’s Write Code!

To connect to the Anthropic API, you’ll need either $ANTHROPIC_API_KEY set in your environment before starting marimo or to add

import os
os.environ["ANTHROPIC_API_KEY"] = "YOUR_ANTHROPIC_API_KEY"

in every notebook as the first cell.

Now we can do a basic test that everything is configured correctly. Put the following code in a cell and run it

from anthropic import Anthropic
client = Anthropic()

response = client.messages.create(
    model="claude-3-7-sonnet-20250219",
    max_tokens=4000,
    messages=[{
        "role": "user",
        "content": "tell me a joke"
        }]
    )

print(response)

If all goes well, you should see a joke, hidden in the raw API output

output from the test showing a joke

At this point you are setup and running

A Note on Structure and Working Methods

Back at the start of this post, I said that I preferred to have a clean working directory and to keep the Anthropic code elsewhere. There’s two main reasons for this:

  1. Marimo uses a different file format and
  2. You’ll be editing the files anyway, so you need to either create a fork or copy code out.

Overall I think that copying code out is cleaner when doing experimentation. This way I can have my own git repo and track my experiments.

Less obviously, the Cookbook is actively having new examples added, but old examples are not updated so you’ll need to make changes even to run them as-is. e.g. the pdf example throws an error No method fitz.open(). The fix is simple: fitz is now pymupdf so change the import

import pymupdf as fitz

but now we’ve diverged from the base repo even to just run the code.

So since I want my own copy anyway, I’m willing to take the small extra conversion step to get the benefits of Marimo.

$ gh repo clone anthropics/anthropic-cookbook
$ cd misc
$ marimo convert pdf_upload_summarization.ipynb -o pdf_upload_summarization.py

And to close, if you do want to just run directly in the repo and convert files as needed, change the first steps above to

$ gh repo clone anthropics/anthropic-cookbook
$ cd anthropic-cookbook

and then setup Marimo as above. Whatever works!