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.

7 min de leitura Equipe python.dev.br

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 normalmente, fazer code review e usar todas as ferramentas de qualidade de código que já conhece.

# 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 tradicional ou o uv, que é significativamente mais rápido:

# Com pip
pip install marimo

# Com uv (recomendado)
uv pip install marimo

# Verificar a instalação
marimo --version

Para iniciar o editor, basta rodar:

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

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ísticaJupyterMarimo
Formato do arquivoJSON (.ipynb)Python puro (.py)
ExecuçãoManual, célula a célulaReativa automática
ReprodutibilidadeDepende da ordem de execuçãoGarantida pelo grafo
Versionamento GitDiffs ilegíveisDiffs limpos
Elementos interativosRequer ipywidgetsNativo (mo.ui)
Deploy como appRequer Voilà/PanelNativo (marimo run)
Estado ocultoComum e perigosoImpossível por design

Para quem usa Jupyter Notebook no dia a dia, a migração é gradual. O Marimo consegue converter notebooks .ipynb existentes:

# 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, no Marimo tudo vem pronto:

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. Você pode consultar bancos de dados ou até DataFrames em memória usando SQL:

@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 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:

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

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

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 e análise com Pandas, o Marimo oferece uma experiência significativamente melhor. Se você já trabalha com ambientes virtuais e ferramentas modernas como uv e Ruff, o Marimo se encaixa naturalmente no seu fluxo de trabalho.

Veja também nosso artigo sobre SQLAlchemy 2.0 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. 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 Rust com PyO3 para criar módulos Python compilados que rodam ordens de magnitude mais rápido.

E

Equipe python.dev.br

Contribuidor do Python Brasil — Aprenda Python em Português