---
title: "cargo tree: Grafo de Dependências Rust | Rust Brasil"
url: "https://rustlang.com.br/blog/cargo-tree-grafo-dependencias-rust-2026/"
markdown_url: "https://rustlang.com.br/blog/cargo-tree-grafo-dependencias-rust-2026.MD"
description: "Use cargo tree para entender dependências Rust, descobrir quem trouxe uma crate, analisar versões duplicadas, features, targets e problemas no Cargo.lock."
date: "2026-08-21"
author: "Equipe Rust Brasil"
---

# cargo tree: Grafo de Dependências Rust | Rust Brasil

Use cargo tree para entender dependências Rust, descobrir quem trouxe uma crate, analisar versões duplicadas, features, targets e problemas no Cargo.lock.


**Use `cargo tree` para enxergar o grafo real que o Cargo resolveu, incluindo dependências transitivas que não aparecem no seu `Cargo.toml`.** Os três comandos mais úteis são `cargo tree` para ver a árvore completa, `cargo tree -i nome-da-crate` para descobrir quem introduziu um pacote e `cargo tree -d` para localizar versões duplicadas.

```bash
cargo tree
cargo tree -i serde
cargo tree -d
```

Essa inspeção responde perguntas que surgem em manutenção, segurança e performance: por que duas versões da mesma crate estão no `Cargo.lock`? Quem trouxe uma biblioteca vulnerável? Qual feature ativou um backend pesado? Por que o binário ganhou dependências depois de uma mudança pequena?

`cargo tree` não modifica o projeto. Ele transforma a resolução do Cargo em uma visão navegável para que você decida o que alterar com contexto.

## Resposta rápida: comandos essenciais

| Objetivo | Comando |
|---|---|
| Ver a árvore de dependências | `cargo tree` |
| Descobrir quem depende de uma crate | `cargo tree -i nome-da-crate` |
| Investigar uma versão específica | `cargo tree -i crate@1.2.3` |
| Mostrar versões duplicadas | `cargo tree -d` |
| Visualizar features ativadas | `cargo tree -e features` |
| Limitar a profundidade | `cargo tree --depth 2` |
| Analisar um pacote do workspace | `cargo tree -p nome-do-pacote` |
| Considerar um target | `cargo tree --target x86_64-unknown-linux-gnu` |
| Evitar a compactação de repetições | `cargo tree --no-dedupe` |

Confira `cargo tree --help` na toolchain instalada antes de automatizar formatos ou opções em scripts críticos. O Cargo evolui, e uma esteira deve fixar a toolchain que validou.

## O que o cargo tree mostra

Um projeto Rust pequeno pode declarar apenas duas dependências:

```toml
[dependencies]
reqwest = { version = "0.12", features = ["json"] }
serde = { version = "1", features = ["derive"] }
```

Mas essas duas linhas podem resolver dezenas de crates transitivas para HTTP, TLS, serialização, parsing de URL, concorrência e integração com o sistema operacional. `cargo tree` apresenta esse resultado hierarquicamente:

```text
meu-app v0.1.0
├── reqwest v0.12.x
│   ├── bytes v1.x
│   ├── http v1.x
│   ├── hyper v1.x
│   ├── serde v1.x
│   └── tokio v1.x
└── serde v1.x
```

A saída exata depende do manifesto, do lockfile, das features, da plataforma e da versão do toolchain. O ponto central é distinguir:

- **dependência direta:** declarada pelo seu pacote;
- **dependência transitiva:** trazida por outra crate;
- **versão resolvida:** versão concreta escolhida pelo resolvedor;
- **feature ativada:** capacidade opcional que pode acrescentar código e dependências;
- **tipo de aresta:** dependência normal, de desenvolvimento ou de build.

Para revisar como `Cargo.toml`, requisitos semânticos e `Cargo.lock` se relacionam, leia o guia de [gerenciamento de dependências em Rust](/artigos/gerenciamento-dependencias/) e a referência do [Cargo](/ecossistema/cargo/).

## Descobrindo quem trouxe uma crate com `-i`

O modo invertido é o recurso mais valioso no diagnóstico diário. Em vez de mostrar “esta crate depende daquelas”, ele responde “quem depende desta crate?”.

```bash
cargo tree -i openssl-sys
```

Uma saída conceitual poderia indicar:

```text
openssl-sys v0.9.x
└── native-tls v0.2.x
    └── hyper-tls v0.6.x
        └── reqwest v0.12.x
            └── meu-app v0.1.0
```

Agora existe um caminho causal: `reqwest` ativou uma integração que chegou a `openssl-sys`. Isso permite investigar se:

- a feature TLS escolhida é intencional;
- o projeto poderia usar outro backend;
- uma dependência direta deixou features padrão ligadas sem necessidade;
- o pacote aparece apenas em testes ou no build;
- a plataforma de deploy realmente precisa desse caminho.

O mesmo método ajuda em um advisory. Se [cargo-audit](/blog/cargo-audit-vulnerabilidades-dependencias-rust-ci-2026/) apontar uma crate transitiva, não comece editando o `Cargo.lock` às cegas. Primeiro execute:

```bash
cargo tree -i crate-afetada
```

Depois identifique o mantenedor da aresta que você controla: sua dependência direta, uma feature, um pacote interno do workspace ou uma build dependency.

### Quando existem várias versões

Se duas versões da crate estão resolvidas, informe a versão na consulta:

```bash
cargo tree -i exemplo@1.4.2
cargo tree -i exemplo@2.0.1
```

Isso separa os caminhos e evita atribuir a versão antiga ao pacote errado.

## Encontrando versões duplicadas com `-d`

Execute:

```bash
cargo tree -d
```

O Cargo destacará crates presentes em múltiplas versões. Duplicidade não significa automaticamente defeito. Ela pode ser necessária quando duas dependências exigem intervalos incompatíveis. Ainda assim, merece investigação porque pode causar:

- compilação repetida de código semelhante;
- binários maiores;
- mais dependências para auditar;
- tipos incompatíveis entre versões da mesma crate;
- migrações mais difíceis;
- comportamento diferente em partes do sistema.

Considere este caso conceitual:

```text
http v0.2.x
└── cliente-legado v1.x

http v1.x
└── reqwest v0.12.x
```

Não é possível “forçar” `http v1` sobre `cliente-legado` se ele realmente depende da linha `0.2`. A correção sustentável pode exigir atualizar ou substituir `cliente-legado`.

O fluxo recomendado é:

```bash
cargo tree -d
cargo tree -i http@0.2.12
cargo tree -i http@1.1.0
```

Depois verifique:

1. há versão mais nova da dependência direta que converge o grafo?
2. uma feature opcional introduz a linha antiga?
3. a duplicidade existe apenas em dev-dependencies?
4. os tipos das duas versões atravessam sua API pública?
5. o custo aparece no artefato final ou somente no build?

Combine essa análise com [cargo-outdated](/blog/cargo-outdated-dependencias-rust-atualizar-2026/) para encontrar atualizações disponíveis. Atualize em lotes pequenos, revise o `Cargo.lock` e rode os testes; não trate toda duplicidade como algo que precisa desaparecer no mesmo pull request.

## Entendendo features com `-e features`

Features são aditivas na maior parte do ecossistema Cargo: quando caminhos diferentes ativam features da mesma crate, o conjunto efetivo tende a ser a união delas para aquela resolução. Isso surpreende quando uma integração aparentemente pequena liga uma árvore grande.

Use:

```bash
cargo tree -e features
```

A saída fica mais detalhada porque passa a mostrar arestas de features. Ela ajuda a responder:

- quem ativou `serde/derive`?
- por que uma crate está compilando suporte a TLS nativo?
- qual pacote habilitou macros ou runtime completo?
- uma feature padrão está adicionando dependências desnecessárias?
- o workspace unificou features que um pacote isolado não ativaria?

Para investigar um pacote específico em um workspace:

```bash
cargo tree -p minha-lib -e features
```

Se o relatório for grande, limite a profundidade ou procure o trecho relevante. Depois compare builds com e sem defaults:

```bash
cargo tree -p minha-lib -e features
cargo tree -p minha-lib -e features --no-default-features
```

A disponibilidade de argumentos de seleção de features acompanha os comandos Cargo; confirme a sintaxe na toolchain local. O objetivo é comparar configurações reais, não produzir uma árvore bonita que nenhum consumidor usa.

Para testar sistematicamente features isoladas e combinações, use [cargo-hack](/blog/cargo-hack-features-powerset-ci-rust-2026/). `cargo tree` explica a matriz; `cargo-hack` verifica se ela compila e funciona.

## Workspaces: qual grafo você está analisando?

Em um workspace, a raiz pode conter bibliotecas, serviços, CLIs, ferramentas de migração e benchmarks. A árvore completa mistura responsabilidades e pode esconder o caminho relevante.

Restrinja por pacote:

```bash
cargo tree -p api
cargo tree -p worker
cargo tree -p minha-lib-publica
```

Compare os resultados para descobrir, por exemplo, por que o serviço HTTP depende de uma crate que a biblioteca pública não deveria expor.

Uma política útil é analisar separadamente:

- pacotes publicados no crates.io;
- aplicações entregues em produção;
- ferramentas internas;
- build dependencies e proc-macros;
- benchmarks e dependências de desenvolvimento.

O guia de [Cargo workspaces e monorepos](/blog/cargo-workspaces-monorepos-rust-2026/) mostra como organizar manifestos compartilhados. A inspeção por pacote evita confundir “está no repositório” com “está neste artefato”.

### Feature unification no workspace

Um pacote pode parecer enxuto quando compilado isoladamente e ganhar features quando o workspace inteiro é resolvido. Isso ocorre porque outro membro depende da mesma crate com capacidades adicionais.

Por isso, compare o contexto que importa para o consumidor:

```bash
cargo tree -p minha-lib -e features
cargo tree --workspace -e features
```

Não conclua que uma biblioteca publicada exige toda feature vista no build monolítico sem testar o pacote no contexto de publicação.

## Targets e dependências condicionais

Manifestos podem declarar dependências por sistema operacional ou arquitetura:

```toml
[target.'cfg(unix)'.dependencies]
nix = "0.29"

[target.'cfg(windows)'.dependencies]
windows-sys = "0.59"
```

Uma árvore observada no Linux não representa necessariamente o build do Windows. Use `--target` para inspecionar a resolução associada ao alvo:

```bash
cargo tree --target x86_64-unknown-linux-gnu
cargo tree --target x86_64-pc-windows-msvc
cargo tree --target wasm32-unknown-unknown
```

O target talvez precise estar instalado para outras etapas do build, mas a inspeção já ajuda a encontrar dependências condicionais e diferenças de plataforma.

Isso é especialmente importante em [cross-compilation com cargo-zigbuild](/blog/cargo-zigbuild-cross-compile-rust-2026/), WebAssembly e embedded. Uma dependência válida no host pode ser incompatível com o alvo final.

## Limitando e formatando relatórios grandes

Em projetos maduros, a árvore completa pode ter centenas de linhas. Comece com uma pergunta específica em vez de colar tudo em uma issue.

### Limite a profundidade

```bash
cargo tree --depth 2
```

Isso oferece uma visão de alto nível das dependências mais próximas do pacote raiz.

### Desative a deduplicação visual

O Cargo normalmente compacta repetições na apresentação para não imprimir a mesma subárvore indefinidamente. Quando você precisa ver cada caminho:

```bash
cargo tree --no-dedupe
```

O relatório cresce bastante. Use apenas durante uma investigação focada.

### Restrinja o pacote

```bash
cargo tree -p meu-binario
```

Essa é quase sempre uma primeira redução melhor do que processar todo o workspace.

### Use consultas invertidas

Quando você já conhece a crate problemática, `-i` é mais informativo do que uma busca textual na árvore completa:

```bash
cargo tree -i crate-problematica
```

## cargo tree para reduzir binário e compilação

A presença no grafo não prova que uma crate domina o tamanho do binário, mas revela os caminhos que merecem medição. Um fluxo de performance pode ser:

1. `cargo tree -d` para localizar duplicidades;
2. `cargo tree -e features` para identificar integrações habilitadas;
3. `cargo tree -i crate-pesada` para encontrar a origem;
4. [cargo-bloat](/blog/cargo-bloat-reduzir-tamanho-binario-rust-2026/) para medir contribuição ao artefato;
5. [cargo-llvm-lines](/blog/cargo-llvm-lines-monomorfizacao-rust-2026/) para investigar geração de código;
6. benchmarks e medições antes de remover capacidades.

Evite a conclusão “muitas dependências são sempre ruins”. Uma crate bem mantida pode economizar código inseguro e trabalho operacional. O problema é depender sem saber por quê, ativar features inúteis ou carregar múltiplas linhas antigas por falta de manutenção.

## cargo tree em segurança e supply chain

O grafo é a superfície real de terceiros do projeto, não apenas a lista curta em `[dependencies]`. Durante uma análise de supply chain, use `cargo tree` para:

- mapear a origem de uma crate com advisory;
- localizar proc-macros e build dependencies;
- entender se uma biblioteca entra apenas em desenvolvimento;
- investigar duplicidades de componentes sensíveis;
- validar a remoção de uma dependência;
- explicar por que uma atualização moveu várias transitivas.

Depois combine o mapa com ferramentas especializadas:

- [cargo-audit](/blog/cargo-audit-vulnerabilidades-dependencias-rust-ci-2026/) para advisories RustSec;
- [cargo-vet](/blog/cargo-vet-auditoria-dependencias-rust-supply-chain-2026/) para auditorias e confiança;
- [cargo-deny e SBOM](/blog/rust-seguranca-supply-chain-cargo-deny-sbom-2026/) para fontes, licenças, bans e inventário;
- [cargo-machete e cargo-udeps](/blog/cargo-machete-cargo-udeps-dependencias-nao-usadas-2026/) para dependências diretas possivelmente sem uso.

Nenhuma dessas ferramentas substitui as outras. `cargo tree` mostra relações; scanners e políticas atribuem significado a elas.

## Comparando o grafo antes e depois de uma mudança

Ao atualizar dependências, salve um relatório de referência:

```bash
cargo tree > /tmp/tree-antes.txt
cargo update -p alguma-crate
cargo tree > /tmp/tree-depois.txt
diff -u /tmp/tree-antes.txt /tmp/tree-depois.txt
```

O diff ajuda a detectar:

- novas dependências transitivas;
- remoções esperadas;
- convergência ou criação de versões duplicadas;
- troca de backend;
- alteração causada por features;
- atualização muito mais ampla do que o pull request sugeria.

Não trate o texto inteiro como artefato estável entre versões de toolchain. Para revisão humana dentro do mesmo ambiente, porém, ele é excelente.

Depois execute a validação normal:

```bash
cargo fmt --check
cargo check --workspace --all-targets
cargo test --workspace
cargo clippy --workspace --all-targets -- -D warnings
```

Se a mudança mexeu em features, expanda a matriz com `cargo-hack`. Se afetou performance ou tamanho, meça o resultado em vez de inferir pela quantidade de linhas da árvore.

## Armadilhas comuns

### Tentar editar uma dependência transitiva diretamente

O caminho sustentável geralmente passa por atualizar a dependência direta, mudar uma feature ou contribuir com o pacote intermediário. Alterar o lockfile manualmente não muda os requisitos do grafo.

### Tratar toda duplicidade como bug

Intervalos incompatíveis podem exigir versões diferentes. Investigue custo e caminhos antes de forçar convergência.

### Analisar apenas a árvore do host

Windows, Linux, macOS, WASM e targets embedded podem resolver conjuntos diferentes. Use o target correspondente ao artefato entregue.

### Ignorar dev e build dependencies

Elas talvez não entrem no binário, mas executam ou compilam em partes importantes da esteira. Proc-macros e scripts de build merecem atenção de supply chain.

### Confundir presença com impacto

Uma crate na árvore não necessariamente ocupa muito espaço nem está no caminho quente. Use ferramentas de medição para tamanho e profiling.

### Rodar `cargo tree` sem uma pergunta

Uma árvore enorme impressiona, mas não produz decisão. Comece por “quem trouxe X?”, “por que existem duas versões de Y?” ou “qual feature ativou Z?”.

## Checklist de diagnóstico

- [ ] executar `cargo tree` para reconhecer o grafo;
- [ ] restringir ao pacote relevante com `-p`;
- [ ] usar `-i` para encontrar a origem da crate investigada;
- [ ] informar `crate@versão` quando houver múltiplas linhas;
- [ ] rodar `cargo tree -d` e classificar duplicidades;
- [ ] inspecionar features com `-e features`;
- [ ] comparar configurações com e sem defaults quando necessário;
- [ ] verificar targets diferentes para dependências condicionais;
- [ ] revisar o diff da árvore antes e depois de atualizações;
- [ ] medir tamanho e performance com ferramentas próprias;
- [ ] rodar auditorias de segurança sobre o `Cargo.lock`;
- [ ] registrar o caminho causal na issue ou pull request.

## cargo tree para carreira e portfólio Rust

Em projetos de portfólio, demonstre que você entende o ecossistema além de adicionar crates. Uma seção de arquitetura pode documentar:

- por que determinado backend TLS foi escolhido;
- como as features mantêm a biblioteca enxuta;
- qual dependência direta introduz componentes críticos;
- como a CI detecta advisories e duplicidades relevantes;
- por que uma versão duplicada foi aceita temporariamente;
- como uma atualização reduziu o grafo ou o tempo de build.

Esse repertório aparece em trabalho de backend, plataforma, segurança, embedded, WebAssembly, bibliotecas e developer tooling. Consulte as [vagas Rust](/vagas/) e observe como responsabilidades de build, CI, supply chain e performance se conectam ao código de produto.

## Perguntas frequentes

### Para que serve o cargo tree?

Ele imprime a resolução de dependências do Cargo em formato hierárquico. Isso inclui transitivas que não aparecem no manifesto do pacote e permite analisar versões, features e caminhos de dependência.

### Como descobrir quem trouxe uma crate?

Use:

```bash
cargo tree -i nome-da-crate
```

Se houver mais de uma versão, consulte `nome-da-crate@versão` para separar os caminhos.

### Como achar dependências duplicadas?

Execute `cargo tree -d`. Depois investigue cada versão com o modo invertido. A meta não é zerar o relatório a qualquer custo, mas entender se existe atualização ou ajuste de feature que converja o grafo com segurança.

### Como ver features ativadas?

Use `cargo tree -e features`. Em workspaces, restrinja com `-p` para entender o pacote relevante e compare as configurações realmente suportadas.

### cargo tree altera arquivos?

Não. Ele inspeciona o grafo resolvido. Mudanças acontecem quando você edita `Cargo.toml`, muda features ou atualiza o `Cargo.lock`.

## Conclusão

`cargo tree` é o mapa do ecossistema que seu projeto realmente compila. Ele revela dependências transitivas, explica quem trouxe uma crate, mostra versões duplicadas e ajuda a rastrear features que expandiram o grafo.

Comece com três comandos:

```bash
cargo tree
cargo tree -i nome-da-crate
cargo tree -d
```

Depois restrinja por pacote, feature e target conforme a pergunta. Combine o resultado com [cargo-outdated](/blog/cargo-outdated-dependencias-rust-atualizar-2026/), auditorias, testes e medições de tamanho. Assim, decisões sobre dependências deixam de ser baseadas em suposição e passam a ter um caminho causal verificável no grafo do Cargo.
