bacon: Feedback Loop Rápido em Rust (além do cargo-watch) | Rust Brasil

Use bacon para check, test, clippy e jobs custom em loop no Rust. Guia com prefs.toml, cargo-watch, nextest, workspaces, TUI e fluxo diário de DX em 2026.

O bacon é a ferramenta certa quando o seu ciclo diário em Rust ainda depende de rodar cargo check na mão — ou de um cargo-watch -x check cru — e você quer erros, testes e Clippy de volta em segundos, com atalhos e jobs nomeados. Instale com cargo install --locked bacon, entre na raiz do crate ou workspace e rode bacon. A TUI passa a observar o projeto, reexecutar o job ativo ao salvar e destacar o que realmente quebrou. Em 2026, para a maioria dos devs Rust no Brasil, isso substitui o cargo-watch como interface principal do feedback loop local.

Este guia explica o que o bacon resolve, como ele se compara ao cargo-watch, como montar prefs.toml com check/test/clippy/nextest, como usar workspaces, o que não misturar com a CI e como encaixar a ferramenta na trilha de DX junto de rust-analyzer, mold e sccache.

Resposta rápida: o fluxo recomendado

EtapaComando ou configuraçãoObjetivo
Instalarcargo install --locked baconDisponibilizar o binário
Loop padrãobaconcargo check contínuo
Testesbacon test ou job nextestFeedback de regressão
Lintbacon clippyQualidade antes do PR
Projetoprefs.toml na raizJobs do time versionados
Usuário~/.config/bacon/prefs.tomlPreferências pessoais
Atalhosteclas na TUITrocar job sem matar o terminal

Antes de copiar jobs para o repositório, confira bacon --help e a documentação atual do projeto: a ferramenta evolui, e fixar a versão do binário no onboarding do time evita “na minha máquina o atalho é outro”.

Por que o feedback loop importa mais que mais uma flag do Cargo

Rust cobra na compilação o que outras linguagens cobram em runtime. Isso é ótimo para produção e pesado no dia a dia se o ciclo for:

  1. editar;
  2. voltar ao terminal;
  3. digitar cargo check ou cargo test;
  4. rolar um wall of text;
  5. voltar ao editor sem contexto.

Em serviços Axum/Tokio, CLIs com clap, crates com features e monorepos, cada ida e volta custa atenção. O rust-analyzer já resolve muita coisa no editor, mas não substitui:

  • um cargo test focado no pacote certo;
  • um clippy com o mesmo conjunto de lints da CI;
  • um job que exercita o binário de integração;
  • a leitura rápida do primeiro erro útil, não do vigésimo warning.

O bacon ataca exatamente essa camada: orquestrar jobs de Cargo de forma contínua, legível e configurável, sem transformar o terminal em um cemitério de sessões watch.

Se o build em si ainda está lento, o bacon não faz milagre sozinho. Combine com o guia de tempo de compilação, mold no Linux e sccache na CI e no laptop. Feedback loop bom + compilação enxuta é o combo que muda a sensação de “Rust é lento para trabalhar”.

O que é bacon

bacon é um background compiler / runner orientado a jobs para projetos Rust. Em termos práticos:

  • observa mudanças no código-fonte;
  • executa um job Cargo (ou comando compatível);
  • renderiza a saída em uma TUI pensada para diagnósticos;
  • permite trocar de job com atalhos em vez de matar e relançar processos.

A metáfora útil é: rust-analyzer é o assistente dentro do editor; bacon é o painel de esteira local ao lado. Um completa o outro. O analyzer mostra erros de tipo enquanto você digita; o bacon valida o contrato que a CI e o cargo “de verdade” enxergam — features, bins, testes de integração, Clippy do workspace.

O bacon não é:

  • um substituto do cargo test na CI;
  • um runner de deploy;
  • um monorepo build system completo (tipo Bazel);
  • um linter próprio — ele chama Clippy, check, test, nextest etc.

Ele é DX pura: menos fricção entre “salvei o arquivo” e “sei se quebrei o crate”.

bacon vs cargo-watch

O ecossistema já conhece o cargo-watch. Vários guias antigos — inclusive menções em posts de ecossistema e como aprender Rust — ensinam:

cargo watch -x check -x test -x run

Isso funciona. Também escala mal em clareza:

Critériocargo-watchbacon
Setup inicialmínimomínimo (bacon)
Jobs nomeadosflags longas na linha de comandoprefs.toml + atalhos
Leitura de erroslog cronológico no terminalTUI focada em diagnósticos
Troca check → test → clippyrelançar processo ou vários -xtrocar job na sessão
Onboarding de timecopiar alias do shellversionar prefs do repo
Scripts headlessexcelentepossível, mas não é o forte
CIàs vezes em devcontainersprefira Cargo direto

Regra prática:

  • use bacon no dia a dia interativo (laptop, Tmux, segundo painel do editor);
  • use cargo-watch quando precisar de um one-liner em script, container efêmero ou demo rápida sem TUI;
  • use Cargo puro na CI e em hooks que precisam de saída determinística e fácil de arquivar.

Não há obrigação de “apagar” o cargo-watch do universo mental. Há obrigação de não ficar preso a ele quando o time já sente dor de DX.

Instalação e primeiros minutos

Instalando

cargo install --locked bacon
bacon --version

Em algumas distros ou setups com pacotes, o binário pode vir de outra fonte. O caminho cargo install --locked é o mais portátil para quem já tem toolchain via rustup.

Rodando no projeto

cd meu-projeto-rust
bacon

O padrão costuma ser um job de check (ou equivalente configurado). Salve um arquivo .rs e observe o ciclo. Se o projeto for workspace, rode na raiz que contém o Cargo.toml workspace — ou configure o pacote alvo no job.

Jobs comuns na linha de comando

bacon check
bacon test
bacon clippy

Os nomes exatos dos jobs dependem da configuração embutida e do seu prefs.toml. O ponto é: você invoca um nome de job, não uma prosa de flags.

Atalhos mentais de fluxo

  1. Comece o dia com bacon no painel lateral.
  2. Enquanto modela tipos e APIs, fique no job de check (rápido).
  3. Ao mexer em comportamento, mude para test ou nextest.
  4. Antes do PR, rode o job de clippy alinhado à CI.
  5. Se o job ficar vermelho, leia o primeiro erro útil na TUI e corrija no editor — o rust-analyzer e o bacon devem convergir.

prefs.toml: a configuração que o time versiona

O diferencial do bacon aparece quando o repositório documenta os jobs. Em vez de cada dev inventar um alias, o projeto declara o contrato de feedback.

Exemplo ilustrativo de prefs.toml na raiz (ajuste nomes e argumentos à versão instalada e ao layout do monorepo):

# Exemplo didático — confira a sintaxe da sua versão do bacon
default_job = "check"

[jobs.check]
command = ["cargo", "check", "--workspace", "--all-targets"]
need_stdout = false

[jobs.test]
command = ["cargo", "test", "--workspace", "--all-targets", "--", "--nocapture"]
need_stdout = true

[jobs.nextest]
command = ["cargo", "nextest", "run", "--workspace"]
need_stdout = true

[jobs.clippy]
command = ["cargo", "clippy", "--workspace", "--all-targets", "--", "-D", "warnings"]
need_stdout = false

[jobs.lib]
command = ["cargo", "check", "-p", "minha_lib", "--all-targets"]
need_stdout = false

Boas práticas de configuração:

  1. Espelhe a CI nos jobs “sérios”. Se a CI roda clippy -D warnings, o job local não pode ser um Clippy permissivo que ensina o time a ignorar lint.
  2. Separe jobs baratos e caros. check no default; test/nextest sob demanda; powerset de features fica com cargo-hack, não no loop a cada keystroke.
  3. Nomeie jobs pelo intento, não pela flag. api, worker, lib, clippy-ci comunicam melhor que c2 ou t.
  4. Versionar prefs.toml do repo alinha onboarding. Preferências puramente pessoais (teclas, tema) ficam no config do usuário.
  5. Documente no README um bloco “DX local: rode bacon”. Isso vale ouro para quem chega no time vindo de Go, Java ou Node.

Workspaces, pacotes e monorepos

Monorepos Rust são o habitat natural do bacon — e também onde a configuração ruim dói mais.

Problemas típicos

  • cargo check na raiz compila 15 crates quando você só editou um helper;
  • testes de integração de um serviço sobem dependências pesadas a cada save;
  • um job genérico esconde que o binário xtask ou um example quebrou;
  • features do workspace fazem o check “verde” no pacote A e vermelho no pacote B.

Táticas

SituaçãoJob sugerido
Dia a dia no crate de libcargo check -p minha_lib --all-targets
API HTTP isoladacargo test -p api --all-targets
Worker assíncronocargo nextest run -p worker
Lint igual à CIcargo clippy --workspace --all-targets -- -D warnings
Release local pontualjob manual, não default

Em workspaces grandes, resista à tentação de colocar tudo no job default. O default precisa ser rápido o bastante para não ser desligado. Jobs completos existem a um atalho de distância.

Se o monorepo usa features complexas, mantenha o bacon no eixo “pacote + check/test” e deixe a matriz de features para cargo-hack em jobs manuais ou na CI.

Integrando nextest, Clippy e a esteira local

nextest

O cargo-nextest melhora paralelismo, isolamento e relatório de testes. No bacon, um job nextest costuma ser a melhor troca de cargo test em repositórios médios e grandes:

  • falhas aparecem mais cedo;
  • retries e particionamento (quando configurados) refletem a CI moderna;
  • o feedback de “suite vermelha” fica legível.

Use cargo test puro só se o projeto ainda não adotou nextest ou se um teste específico depende de comportamento legado.

Clippy

Clippy no loop local evita a clássica dança “passei no check e o PR quebrou no lint”. Alinhe:

  • mesmos -D warnings (ou allowlist) da CI;
  • mesmos targets (--all-targets quando a CI usa);
  • mesmos pacotes relevantes.

O bacon não “é” o Clippy; ele só garante que você o rode antes de abrir o merge request.

check vs build vs run

JobQuando usar
checkmodelagem de tipos, refactors, 90% do dia
test / nextestcomportamento, regressões, refactors arriscados
clippyhigiene antes de PR e em limpeza de dívida
buildquando o link ou o artefato importam de verdade
runCLIs e bins em que ver a saída importa mais que o diagnóstico

Para a maioria das sessões de backend e bibliotecas, check + nextest sob demanda é o par vencedor. build completo a cada save só se justifica se o gargalo de link já foi tratado (por exemplo com mold).

O que o bacon não deve fazer

1. Substituir a CI

Se o verde local depende de um job exótico só documentado no prefs.toml e a CI roda outra coisa, o time aprende a mentir para si mesmo. O bacon antecipa a CI; não a redefine em silêncio.

2. Esconder builds lentos

Se cada ciclo demora 40 segundos, a dor é de compilação, não de TUI. Meça com cargo build --timings, ataque monomorfização, cache e link — veja otimizar build, cargo-llvm-lines e sccache.

3. Rodar powerset de features a cada save

A matriz de features é cara por natureza. cargo-hack entra em jobs manuais, nightly ou CI — não no default do bacon.

4. Competir com o rust-analyzer

Não desligue o analyzer “porque o bacon já checa”. São camadas diferentes: um é interativo no buffer; o outro valida o grafo Cargo completo e os testes.

5. Virar desculpa para não escrever testes

Feedback loop rápido sem testes só te diz que o código compila. Combine com a trilha de estratégias de testes em Rust.

Receita de estação de trabalho Rust em 2026

Um setup coeso, alinhado ao que o site já cobre:

  1. Editor + rust-analyzer bem configurado (guia).
  2. bacon no painel lateral com jobs check, nextest, clippy.
  3. mold no Linux para link incremental (guia).
  4. sccache se você alterna branches/toolchains com frequência (guia).
  5. nextest como runner de testes local e de CI (guia).
  6. cargo-hack para features quando o crate publica flags (guia).
  7. CI com os mesmos comandos dos jobs sérios — sem depender da TUI.

Esse pacote é o que separa “consigo compilar Rust” de “consigo manter um serviço Rust com ritmo de produto”.

bacon no dia a dia: cenários reais

Biblioteca publicada em crates.io

  • Default: check -p lib --all-targets.
  • Antes de versionar: job de testes + Clippy + (fora do loop) semver-checks e matriz de features.

API Axum em workspace

  • Default: check só do pacote api.
  • Ao mexer em handlers: nextest do pacote api.
  • Ao mexer em crate compartilhado domain: check de domain + testes dos consumidores principais.

CLI com clap

  • Default: check do bin.
  • Job run opcional para smoke visual.
  • Testes de parsing e exit codes com nextest.

Time misto (júnior + sênior)

  • prefs.toml no repo com três jobs óbvios: check, test, clippy.
  • README com “abra o projeto e rode bacon”.
  • Code review recusa PR que só passou no analyzer do editor sem Clippy alinhado.

Armadilhas comuns

Job default lento demais

Se o default executa a suíte inteira do monorepo, alguém vai desligar o bacon. Mantenha o default barato.

Saída barulhenta

Warnings que não quebram a CI mas inundam a TUI treinam cegueira. Alinhe lints ou filtre com a mesma política do pipeline.

Config só na máquina de uma pessoa

DX de time precisa de arquivo versionado. Alias no zsh do lead não escala.

Misturar run com efeitos colaterais

Job que sobe servidor, mexe em banco local ou publica mensagem em fila não é bom default de watch. Separe smoke jobs conscientes.

Ignorar falhas de toolchain

bacon herda a toolchain ativa do diretório (rustup override, rust-toolchain.toml). Se a CI usa 1.8x e o laptop está em nightly sem querer, o verde local mente. Trate MSRV e toolchains como parte do DX.

Achar que TUI = cobertura

Um job verde de check não prova concorrência, I/O ou contratos HTTP. Continua sendo necessário testar de verdade.

Checklist de adoção

  1. Instale com cargo install --locked bacon e rode bacon na raiz.
  2. Confirme que o job default é rápido o bastante para uso contínuo.
  3. Crie prefs.toml com check, test/nextest e clippy.
  4. Alinhe os argumentos dos jobs sérios com a CI.
  5. Em workspace, limite o default ao pacote ou conjunto quente.
  6. Documente no README o fluxo de DX local.
  7. Combine com rust-analyzer; não desligue o editor intelligence.
  8. Se o ciclo ainda for lento, meça build/link/cache antes de culpar a TUI.
  9. Deixe matriz de features e auditorias pesadas fora do loop a cada save.
  10. Revise a config a cada mudança grande de CI.

bacon e carreira Rust

Em vagas e entrevistas de backend, plataforma e sistemas, “como você encurta o ciclo de feedback em Rust?” é uma pergunta de maturidade. Respostas fracas citam só o analyzer. Respostas fortes descrevem:

  • jobs locais alinhados à CI;
  • diferença entre check, test e lint no loop;
  • trade-offs de monorepo;
  • ferramentas de build (mold, sccache) e de teste (nextest);
  • por que watch ingênuo não escala em time.

Saber montar uma estação com bacon + nextest + Clippy + CI espelhada demonstra que você entrega velocidade sustentável, não apenas código que compila. Isso combina com a narrativa de carreira em Rust e com a prática de quem mantém crates ou serviços reais no Brasil.

Para portfólio, um bom detalhe em README de projeto open source é a seção “Desenvolvimento: cargo install bacon && bacon”, com jobs documentados. É sinal de cuidado com quem for contribuir — e recrutadores técnicos notam.

Perguntas frequentes

Preciso desinstalar cargo-watch?

Não. Mantenha-o se scripts e tutoriais legados dependem dele. No fluxo interativo diário, prefira bacon.

bacon funciona no Windows e no macOS?

Sim para o fluxo geral de jobs Cargo. Detalhes de notificação, atalhos e performance de filesystem variam por SO; o contrato principal — observar, rodar, mostrar — permanece. Ajuste expectativas de link rápido: mold é história sobretudo Linux.

Posso usar bacon com just, make ou xtask?

Sim, se o job chamar o comando que você já usa. O valor está em ter um painel reativo; o motor pode ser Cargo direto ou um wrapper do repositório. Evite wrappers opacos que escondem a falha real.

O bacon substitui testes na IDE?

Não. Ele complementa. Muitos times usam rust-analyzer + CodeLLDB/editor tests para o micro e bacon nextest para o meso.

E se o projeto for minúsculo?

Ainda vale: bacon no default de check já remove atrito. A configuração elaborada só aparece quando o workspace cresce.

Como versionar a ferramenta no time?

Documente a versão mínima no README ou no onboarding, use cargo install --locked e, se necessário, pin em scripts de bootstrap. O importante é todos rodarem jobs com a mesma semântica.

Conclusão

O gargalo de produtividade em Rust raramente é “falta de mais uma crate”. Quase sempre é o ciclo editar → validar → corrigir. O bacon encurta esse ciclo com jobs nomeados, TUI legível e configuração compartilhável — um passo além do cargo-watch genérico.

Adote o default barato (check), tenha nextest e clippy a um atalho, espelhe a CI e combine com analyzer, linker e cache. O resultado é um fluxo em que Rust continua rigoroso na compilação, mas o dia a dia deixa de parecer punição.

Continue a trilha de tooling com cargo-nextest, cargo-hack, mold, sccache, rust-analyzer e otimização de tempo de compilação. Juntas, essas peças formam a estação de trabalho que sustenta crates, APIs e monorepos Rust de verdade.