Back

Removendo Arquivos e Dependências Não Utilizadas com Knip

Removendo Arquivos e Dependências Não Utilizadas com Knip

Todo projeto JavaScript e TypeScript acumula desordem ao longo do tempo: uma dependência instalada para um experimento rápido, um arquivo utilitário deixado para trás após uma refatoração, uma função exportada que ninguém mais importa. Individualmente, esses casos parecem inofensivos. Coletivamente, eles tornam os builds mais lentos, inflam o node_modules, geram ruído de segurança e tornam as bases de código mais difíceis de navegar.

A resposta tradicional é uma auditoria manual: usar grep para nomes de pacotes, procurar referências de arquivos, conferir o package.json manualmente. Funciona, mas não escala. É aí que entra o Knip.

Principais Conclusões

  • Dependências não utilizadas e código morto aumentam o tempo de build, incham os bundles e geram ruído de segurança e licenciamento.
  • O Knip analisa todo o seu repositório como um linter em nível de projeto, reportando arquivos, exports, dependências não utilizadas e imports não listados.
  • A flag --fix aplica limpezas automáticas, enquanto --allow-remove-files estende isso para excluir arquivos não utilizados.
  • Executar o Knip no CI ajuda a evitar o acúmulo de código morto e complementa o ESLint e seu formatador.

Por Que Dependências Não Utilizadas e Código Morto Valem a Pena Corrigir

Pacotes não utilizados no package.json não são apenas ruído cosmético. Eles:

  • Aumentam o tempo de instalação e o uso de disco do node_modules
  • Podem acabar nos bundles de produção se seu bundler não fizer tree-shake corretamente
  • Disparam alertas falsos de segurança em ferramentas como o Dependabot
  • Podem ter licenças restritivas que tecnicamente se aplicam ao seu projeto
  • Trazem dependências transitivas com os mesmos problemas

Código morto tem custos similares. Exports não utilizados e arquivos não referenciados tornam mais difícil entender o que uma base de código realmente faz, e desaceleram linters e verificadores de tipo que precisam processá-los de qualquer forma.

O Que o Knip Faz de Diferente

Ferramentas como depcheck e ts-prune abordavam partes desse problema, mas ambos os projetos foram arquivados em 2025. O Knip surgiu como uma substituição moderna que combina análise de dependências, exports e arquivos em uma única ferramenta ativamente mantida.

Pense no Knip como um linter em nível de projeto. Enquanto o ESLint verifica arquivos individuais, o Knip analisa todo o repositório: pontos de entrada, grafos de importação, exports e package.json em conjunto. Ele reporta arquivos não utilizados, exports não utilizados, dependências não utilizadas e pacotes que são importados mas estão ausentes do package.json.

O Knip funciona com npm, pnpm, Yarn e Bun, e requer Node.js 20.19+ ou Bun para ser executado.

Começando em Cinco Minutos

Inicialize o Knip no seu projeto com:

npm init @knip/config

Isso cria um arquivo de configuração knip.json com padrões sensatos. Em seguida, execute a análise:

npx knip

O Knip emite um relatório agrupado por tipo de problema: arquivos não utilizados, exports não utilizados, dependências não utilizadas e dependências não listadas. Em uma primeira execução em um projeto antigo, a lista pode ser longa — isso é esperado.

Aplicando Correções com Segurança

Depois de revisar o relatório e confirmar que ele parece preciso, o Knip pode aplicar correções automáticas revisáveis:

npx knip --fix

Isso remove palavras-chave export de exports não utilizados, limpa o package.json e lida com re-exports e membros de enum do TypeScript. Para também excluir arquivos não utilizados:

npx knip --fix --allow-remove-files

Sempre revise as alterações no Git antes de fazer commit. O Knip é conservador por design, mas o auto-fix modifica arquivos reais. Um rápido git diff antes de fazer o stage é um bom hábito.

Você também pode mirar em tipos específicos de problemas para manter as mudanças pequenas e revisáveis:

npx knip --fix-type dependencies
npx knip --fix-type exports,types

Quando o Knip Precisa de Uma Ajudinha

O Knip não é uma caixa-preta perfeita. Algumas situações exigem configuração manual:

  • Imports dinâmicos (import(someVariable)) não podem ser resolvidos estaticamente
  • Convenções de framework (arquivos de página do Next.js, módulos virtuais do Vite) podem precisar de configuração de plugin ou regras de ignore
  • Arquivos gerados normalmente devem ser excluídos da análise
  • Monorepos funcionam bem por padrão, mas referências entre workspaces às vezes precisam de configuração explícita

Se você estiver vendo falsos positivos, adicione uma entrada ignore ou ignoreDependencies ao knip.json em vez de desabilitar seções inteiras da análise.

Transformando a Limpeza em um Hábito

O uso mais eficaz do Knip não é uma auditoria pontual — é executá-lo regularmente. Adicione-o ao seu pipeline de CI junto com seu linter e verificador de tipos:

npx knip --reporter compact

Um relatório limpo em cada pull request ajuda a evitar que código morto se acumule em primeiro lugar. Combine o Knip com o ESLint (para variáveis não utilizadas dentro dos arquivos) e o formatador de sua escolha, e você terá um ciclo de manutenção sólido e automatizado que mantém seus projetos JavaScript e TypeScript enxutos, sem trabalho de detetive manual.

Conclusão

O Knip transforma a tarefa tediosa de caçar arquivos, exports e dependências não utilizados em uma etapa repetível e automatizada. Ao tratar a limpeza como parte do seu fluxo de trabalho regular em vez de uma faxina ocasional, você mantém seu projeto enxuto, seus builds rápidos e sua superfície de dependências pequena. Comece com uma única execução de npx knip, integre os resultados ao seu CI e deixe a ferramenta fazer o trabalho de detetive que você costumava fazer manualmente.

FAQs

Sim, o Knip apenas reporta problemas por padrão e não faz alterações a menos que você passe a flag --fix. Execute-o primeiro para revisar o relatório, depois aplique correções de forma incremental usando --fix-type para mirar em uma categoria por vez. Sempre revise o diff do Git antes de fazer commit, especialmente ao usar --allow-remove-files.

O Knip combina as responsabilidades de ambas as ferramentas em um único pacote ativamente mantido. O depcheck foca em dependências e o ts-prune em exports TypeScript não utilizados, mas o Knip analisa arquivos, exports e dependências em conjunto através de workspaces, produzindo resultados mais precisos para projetos modernos.

Falsos positivos geralmente vêm de imports dinâmicos, convenções de framework ou arquivos gerados que o Knip não consegue resolver estaticamente. Verifique se existe um plugin do Knip para o seu framework, depois adicione entradas ignore ou ignoreDependencies no knip.json para os casos restantes. Evite desabilitar seções inteiras da análise para preservar a cobertura.

Sim, e é aí que ele fornece mais valor. Adicione npx knip --reporter compact ao seu pipeline de CI para que cada pull request seja verificado quanto a novo código morto. Combinado com o ESLint e seu formatador, isso cria um ciclo de manutenção automatizado que ajuda a evitar o acúmulo de arquivos e dependências não utilizadas entre releases.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay