---
title: "Marimo: O Notebook Reativo que Substitui o Jupyter"
url: "https://python.dev.br/blog/marimo-notebook-reativo-python/"
markdown_url: "https://python.dev.br/blog/marimo-notebook-reativo-python.MD"
description: "Conheça o Marimo, notebook reativo para Python com execução automática, versionamento Git nativo e deploy como app web. Guia prático com exemplos."
date: "2026-04-24"
author: "Equipe python.dev.br"
---

# Marimo: O Notebook Reativo que Substitui o Jupyter

Conheça o Marimo, notebook reativo para Python com execução automática, versionamento Git nativo e deploy como app web. Guia prático com exemplos.


Se você trabalha com ciência de dados, análise exploratória ou prototipagem em Python, provavelmente já enfrentou os problemas clássicos do Jupyter: células executadas fora de ordem, estado oculto que quebra a reprodutibilidade e arquivos `.ipynb` que são um pesadelo para versionar com Git. O **Marimo** surgiu como uma alternativa moderna que resolve esses problemas de forma elegante.

Com mais de 15 mil estrelas no GitHub e adoção por empresas como Cloudflare, Shopify e BlackRock, o Marimo se consolidou em 2026 como a principal alternativa ao Jupyter para quem quer notebooks reproduzíveis, reativos e versionáveis. Neste artigo, vamos explorar como ele funciona, como instalar e criar seu primeiro notebook reativo.

## O que torna o Marimo diferente?

O conceito central do Marimo é a **reatividade**. Quando você executa uma célula ou interage com um elemento de UI, o Marimo automaticamente executa todas as células que dependem das variáveis modificadas. Isso elimina o problema mais comum do Jupyter: rodar células fora de ordem e obter resultados inconsistentes.

Além disso, notebooks Marimo são armazenados como **arquivos Python puros** (`.py`), não como JSON. Isso significa que você pode versionar com [Git](/glossario/git/) normalmente, fazer code review e usar todas as ferramentas de qualidade de código que já conhece.

```python
# Um notebook Marimo é um arquivo .py normal
import marimo

app = marimo.App()

@app.cell
def __():
    import pandas as pd
    dados = pd.DataFrame({
        "cidade": ["São Paulo", "Rio de Janeiro", "Belo Horizonte"],
        "populacao": [12_300_000, 6_700_000, 2_500_000]
    })
    return dados,

@app.cell
def __(dados):
    # Esta célula re-executa automaticamente quando 'dados' muda
    total = dados["populacao"].sum()
    print(f"População total: {total:,.0f}")
    return total,
```

## Instalando o Marimo

A instalação é simples. Você pode usar o [pip](/glossario/pip/) tradicional ou o [uv](/blog/uv-gerenciador-pacotes-python/), que é significativamente mais rápido:

```python
# Com pip
pip install marimo

# Com uv (recomendado)
uv pip install marimo

# Verificar a instalação
marimo --version
```

Para iniciar o editor, basta rodar:

```bash
# Criar um novo notebook
marimo edit meu_notebook.py

# Ou abrir um existente
marimo edit analise.py
```

O Marimo abre uma interface web moderna no navegador, com suporte a temas claro e escuro, autocompletar e formatação integrada.

## Reatividade na prática

A reatividade do Marimo funciona através de um **grafo de dependências** entre células. O runtime analisa quais variáveis cada célula define e quais ela consome, construindo automaticamente a ordem correta de execução.

```python
import marimo as mo

@app.cell
def __():
    # Célula 1: define os dados base
    import pandas as pd

    vendas = pd.DataFrame({
        "produto": ["Widget A", "Widget B", "Widget C"] * 4,
        "mes": ["Jan", "Fev", "Mar", "Abr"] * 3,
        "valor": [1500, 2300, 1800, 2100, 1900, 2500,
                  1700, 2200, 2000, 2400, 1600, 2800]
    })
    return vendas,

@app.cell
def __():
    # Célula 2: slider interativo para filtrar valor mínimo
    slider = mo.ui.slider(
        start=1000, stop=3000, step=100,
        value=1500, label="Valor mínimo (R$)"
    )
    slider
    return slider,

@app.cell
def __(vendas, slider):
    # Célula 3: filtra automaticamente quando o slider muda
    filtrado = vendas[vendas["valor"] >= slider.value]

    resumo = filtrado.groupby("produto")["valor"].agg(["sum", "mean", "count"])
    resumo.columns = ["Total", "Média", "Qtd"]

    mo.md(f"""
    ### Vendas acima de R$ {slider.value:,.0f}

    {mo.as_html(resumo)}

    **{len(filtrado)}** registros encontrados de **{len(vendas)}** totais.
    """)
    return filtrado, resumo,
```

Quando o usuário move o slider, as células 3 em diante re-executam automaticamente. Sem callbacks manuais, sem estado inconsistente.

## Marimo vs Jupyter: comparativo prático

| Característica | Jupyter | Marimo |
|---|---|---|
| Formato do arquivo | JSON (.ipynb) | Python puro (.py) |
| Execução | Manual, célula a célula | Reativa automática |
| Reprodutibilidade | Depende da ordem de execução | Garantida pelo grafo |
| Versionamento Git | Diffs ilegíveis | Diffs limpos |
| Elementos interativos | Requer ipywidgets | Nativo (mo.ui) |
| Deploy como app | Requer Voilà/Panel | Nativo (marimo run) |
| Estado oculto | Comum e perigoso | Impossível por design |

Para quem usa [Jupyter Notebook](/glossario/jupyter-notebook/) no dia a dia, a migração é gradual. O Marimo consegue converter notebooks `.ipynb` existentes:

```bash
# Converter um notebook Jupyter para Marimo
marimo convert meu_notebook.ipynb -o meu_notebook.py

# Abrir o notebook convertido
marimo edit meu_notebook.py
```

## Elementos de UI nativos

Uma das maiores vantagens do Marimo sobre o Jupyter é o suporte nativo a elementos interativos sem dependências extras. Enquanto no Jupyter você precisa instalar e configurar o [ipywidgets](https://ipywidgets.readthedocs.io/), no Marimo tudo vem pronto:

```python
import marimo as mo

@app.cell
def __():
    # Formulário completo com vários tipos de input
    form = mo.ui.batch(
        nome=mo.ui.text(label="Nome do projeto"),
        linguagem=mo.ui.dropdown(
            options=["Python", "JavaScript", "Go", "Rust"],
            value="Python",
            label="Linguagem principal"
        ),
        publico=mo.ui.switch(label="Repositório público"),
        prioridade=mo.ui.slider(
            start=1, stop=5, value=3,
            label="Prioridade"
        ),
    )
    form
    return form,

@app.cell
def __(form):
    # Reage automaticamente a mudanças no formulário
    config = {
        "nome": form.value["nome"],
        "linguagem": form.value["linguagem"],
        "visibilidade": "pública" if form.value["publico"] else "privada",
        "prioridade": form.value["prioridade"],
    }

    mo.md(f"""
    ### Configuração do Projeto

    | Campo | Valor |
    |---|---|
    | Nome | {config['nome']} |
    | Linguagem | {config['linguagem']} |
    | Visibilidade | {config['visibilidade']} |
    | Prioridade | {'*' * config['prioridade']} |
    """)
    return config,
```

Os elementos disponíveis incluem: `text`, `number`, `slider`, `dropdown`, `multiselect`, `switch`, `checkbox`, `radio`, `date`, `file`, `table` (com seleção de linhas) e `plot` (gráficos interativos).

## SQL integrado

O Marimo tem suporte nativo a consultas SQL que se integram diretamente com [DataFrames do Pandas](/glossario/pandas/). Você pode consultar bancos de dados ou até DataFrames em memória usando SQL:

```python
@app.cell
def __(vendas):
    # Consultar um DataFrame com SQL diretamente
    resultado = mo.sql(f"""
        SELECT produto,
               SUM(valor) as total_vendas,
               AVG(valor) as media_vendas
        FROM vendas
        GROUP BY produto
        ORDER BY total_vendas DESC
    """)
    return resultado,
```

Essa integração é especialmente útil para quem trabalha com [DuckDB](/blog/python-e-duckdb-analytics/) ou precisa fazer análises exploratórias rápidas combinando Python e SQL.

## Deploy como aplicação web

Diferente do Jupyter, onde você precisa de ferramentas adicionais como Voilà ou Panel para transformar um notebook em uma aplicação web, o Marimo faz isso nativamente:

```bash
# Rodar o notebook como uma aplicação web (sem código visível)
marimo run analise.py

# Servir na rede local para compartilhar com a equipe
marimo run analise.py --host 0.0.0.0 --port 8080
```

O comando `marimo run` esconde o código e mostra apenas os outputs e elementos interativos, criando uma aplicação web completa. Isso é ideal para [dashboards](/blog/criando-dashboards-com-streamlit/) internos, relatórios interativos e protótipos.

## Marimo com IA: o recurso pair

Em 2026, o Marimo introduziu o **marimo pair**, um sistema de colaboração com agentes de IA diretamente no notebook. O agente pode gerar código, criar visualizações e iterar sobre análises com contexto completo do notebook.

```python
@app.cell
def __():
    # O marimo pair permite interação com IA dentro do notebook
    # O agente tem acesso ao contexto completo: variáveis, imports, outputs

    # Exemplo: pedir ao agente para criar uma visualização
    # usando mo.ai.chat() integrado ao notebook
    chat = mo.ui.chat(
        mo.ai.llm.openai("gpt-4o"),
        prompts=["Crie um gráfico de barras com os dados de vendas"],
    )
    chat
    return chat,
```

Essa funcionalidade posiciona o Marimo como uma ferramenta que vai além de notebooks tradicionais, integrando fluxos de trabalho com [LLMs e APIs de inteligência artificial](/blog/python-e-llms-apis-inteligencia-artificial/).

## Quando usar Marimo em vez de Jupyter

O Marimo é a melhor escolha quando você precisa de:

- **Reprodutibilidade garantida**: análises científicas, relatórios regulatórios, pipelines de dados
- **Colaboração com Git**: projetos em equipe onde code review importa
- **Aplicações interativas**: dashboards, ferramentas internas, protótipos
- **Exploração de dados**: análises ad-hoc com elementos interativos nativos

O Jupyter ainda faz sentido quando você precisa de compatibilidade com ecossistemas existentes (Google Colab, Kaggle), quando usa kernels não-Python (R, Julia), ou quando seu time já tem uma infraestrutura consolidada de JupyterHub.

Para projetos novos em Python, especialmente os que envolvem [ciência de dados](/blog/python-para-ciencia-de-dados/) e [análise com Pandas](/glossario/pandas/), o Marimo oferece uma experiência significativamente melhor. Se você já trabalha com [ambientes virtuais](/glossario/virtualenv/) e ferramentas modernas como [uv](/blog/uv-gerenciador-pacotes-python/) e [Ruff](/blog/ruff-linter-formatador-python/), o Marimo se encaixa naturalmente no seu fluxo de trabalho.

Veja também nosso artigo sobre [SQLAlchemy 2.0](/blog/sqlalchemy-2-orm-moderno-python/) para aprender a usar o ORM mais popular do Python com as melhores práticas modernas.

## Conclusão

O Marimo representa uma evolução natural dos notebooks Python. A reatividade elimina a classe inteira de bugs causados por estado oculto, o formato Python puro resolve o problema de versionamento, e o deploy nativo como app web remove a necessidade de ferramentas adicionais.

A curva de aprendizado é mínima para quem já usa Jupyter. A principal mudança mental é aceitar que as células não precisam de uma ordem fixa — o grafo de dependências cuida disso automaticamente. Depois de experimentar, é difícil voltar para o modelo tradicional.

Para começar, instale com `uv pip install marimo`, converta um notebook existente com `marimo convert`, e explore a documentação oficial em [marimo.io](https://marimo.io). Em poucos minutos você vai entender por que tantos desenvolvedores estão migrando.

Se você precisa integrar código nativo de alta performance nos seus notebooks, vale explorar extensões em <a href="https://rustlang.com.br/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'rustlang.com.br' })">Rust com PyO3</a> para criar módulos Python compilados que rodam ordens de magnitude mais rápido.
