A página do repositório no GitHub expõe pushed_at, um timestamp que pode avançar sempre que qualquer branch recebe um push. Isso pode divergir do commit mais recente na branch padrão. A data da branch padrão é um sinal de manutenção do repositório; ela não é necessariamente o código que um gerenciador de pacotes instala.
Normalmente, os gerenciadores de pacotes resolvem artefatos do registry ou versões de módulos. Por isso, esta auditoria analisa separadamente a atividade do repositório e o artefato publicado: um pode estar em dia enquanto o outro já ficou para trás.
Então eu selecionei 35 repositórios que ainda aparecem em recomendações e fui atrás do número que o GitHub não mostra no cabeçalho: a data do commit mais recente na branch padrão.
A discrepância é real: 14 dos 35 têm um pushed_at mais de 180 dias à frente do último commit da branch padrão, chegando a 1.802 dias. Em três desses 14, há confirmação positiva de bots; depois de aplicar filtros de arquivamento e atividade humana, restam dois casos confirmados de bot entre nove candidatos. A descoberta mais útil é que a recência do repositório e a do artefato publicado podem seguir ritmos diferentes.
O que foi medido e com base em quê

Referência oficial: API de repositórios do GitHub.
Todos os números aqui foram lidos de uma resposta ativa de API entre 15:44 e 15:53 UTC em 2026-07-27 e armazenados em cache. O dataset com 35 linhas, a lista de repositórios, as linhas montadas e os scripts de fetch/build em artifacts/ preservam as entradas da auditoria e o código de transformação.
Foram coletadas quatro categorias de dados; as solicitações de registry e de atividade foram condicionais, e não uma sequência fixa de quatro chamadas:
GET /repos/{owner}/{repo}— estrelas,archived,pushed_at, licença,default_branch.GET /repos/{o}/{r}/commits?sha={default_branch}&per_page=1— o commit mais recente da branch padrão, usado como sinal de manutenção do repositório.GET /repos/{o}/{r}/activity?per_page=30— para todo repositório em que os dois campos divergem, o que de fato movimentoupushed_at.GET /repos/{o}/{r}/releases+ os registries do PyPI e do npm — quando o artefato foi lançado pela última vez, o que acaba importando mais do que os dois anteriores.
staleness_days é o tempo decorrido entre o commit da branch padrão e o momento de referência. A diferença entre pushed_at e esse commit é a ilusão, medida em dias. Qualquer valor acima de 180 dias é sinalizado.
Há dois critérios importantes que mudaram os resultados.
A atribuição do pacote foi verificada, nunca presumida. Um pacote cujo README menciona um repositório não é, automaticamente, o pacote desse repositório. Todo mapeamento precisou ser confirmado por um campo estruturado — a entrada repository/project_urls do próprio registry, ou um manifest comitado dentro do repositório. Seis mapeamentos aparentemente plausíveis falharam nesse teste, e seus números de download foram deliberadamente não atribuídos.
Um desses casos rejeitados vale a regra inteira. curl-cffi soma 35.763.529 downloads por mês e parece, à primeira vista, ser o binding Python de lwthiker/curl-impersonate — um repositório sem atividade há 875 dias. Atribuí-lo produziria um número quarenta e quatro vezes maior que o de newspaper3k, e seria falso: os metadados do próprio PyPI de curl-cffi apontam para lexiforest/curl_cffi, um projeto separado e ainda mantido, com último lançamento em 2026-04-03. O número mais espetacular disponível aqui era justamente o errado.
Um sétimo caso é ainda mais estranho: steel-dev/steel-mcp-server declara @steel-dev/mcp-server no próprio package.json, mas o npm retorna 404. Ele nunca foi publicado, então não faz sentido dizer que “ainda está sendo instalado”.
Quando um número não pôde ser obtido, isso foi dito explicitamente. Ferramentas em Go, JVM, .NET e PHP não têm presença no PyPI ou npm, então aparecem como N/A (no PyPI/npm package) — nunca como zero. Dezessete dos 35 não publicam GitHub Releases; isso foi registrado como none, e não como dado ausente.
Esses campos não foram colapsados propositalmente em um único “score de saúde”. Uma branch padrão defasada, uma side branch recente, a ausência de GitHub Release e um artefato antigo do registry respondem perguntas diferentes. A evidência linha a linha está disponível no dataset com 35 linhas, com os inputs dos repositórios e os registros montados ao lado. Leia isso como sinais de triagem que definem a próxima checagem, e não como quatro votos sobre se um projeto está vivo.
A ressalva da amostra, logo de início
Esta é uma lista manual de ferramentas que eu suspeitava estarem surfando na própria reputação. Não é uma amostra aleatória do ecossistema de scraping, e “31 de 35 estão defasados” não é uma taxa do ecossistema — é, no máximo, uma medida de quão bem eu escolhi os casos. O resultado interessante não é a contagem de itens defasados. É que, mesmo numa amostra selecionada para mostrar esse fenômeno, o mecanismo específico que eu estava testando explica só uma minoria dos casos, e pôde ser confirmado de forma positiva em ainda menos.
A ilusão é real, e este é o pior caso
sjdirect/abot, um crawler .NET com 2.308 estrelas. O GitHub mostra um push em 2026-07-17, dez dias antes da data de referência. A branch padrão foi tocada pela última vez em 2021-08-09.
Isso dá uma diferença de 1.802 dias. Cinco anos. O cabeçalho diz “semana passada”.
Quatorze dos 35 repositórios mostram uma diferença acima de 180 dias:
| Repositório | Diferença (dias) | Última movimentação na branch padrão | pushed_at |
|---|---|---|---|
sjdirect/abot | 1.802 | 2021-08-09 | 2026-07-17 |
dragnet-org/dragnet | 1.520 | 2021-05-09 | 2025-07-08 |
paquettg/php-html-parser | 1.376 | 2020-11-01 | 2024-08-09 |
seomoz/simhash-py | 1.159 | 2020-03-12 | 2023-05-15 |
internetarchive/wayback | 1.039 | 2021-04-27 | 2024-03-01 |
Rhizome-Conifer/conifer | 1.013 | 2023-10-12 | 2026-07-22 |
kohlschutter/boilerpipe | 856 | 2015-08-30 | 2018-01-03 |
scrapinghub/splash | 819 | 2022-05-05 | 2024-08-02 |
tomnomnom/waybackurls | 756 | 2022-04-05 | 2024-05-01 |
geziyor/geziyor | 689 | 2024-08-12 | 2026-07-02 |
crawlab-team/crawlab | 488 | 2024-10-09 | 2026-02-10 |
ArchiveTeam/wpull | 468 | 2023-01-16 | 2024-04-29 |
yasserg/crawler4j | 396 | 2020-10-03 | 2021-11-04 |
apache/any23 | 381 | 2022-06-03 | 2023-06-20 |
Quatorze em trinta e cinco. Real, relevante e uma minoria de uma amostra escolhida justamente para conter isso.
Bots foram confirmados em três repositórios sinalizados — e dois permanecem após filtros
A versão popular dessa história sempre cita dependabot. Eu verifiquei isso puxando o feed de atividade de cada repositório sinalizado e classificando cada ref enviado depois do último commit da branch padrão. Esse “depois” importa: eventos anteriores ao último commit não dizem nada sobre o que inflou a diferença, e contar o feed inteiro muda a pergunta de forma silenciosa.
Confirmado como bot, usando o método pós-commit: três. scrapinghub/splash (4 de 4 eventos pós-commit em dependabot/pip/*), geziyor/geziyor (5 de 5 em dependabot/go_modules/*), apache/any23 (16 de 16 em dependabot/maven/*). Um desses três, any23, está formalmente arquivado, então nunca entra no conjunto filtrado — restando dois casos confirmados que também satisfazem todas as outras condições.
Totalmente errado: dois, e ambos são mais interessantes do que a história dos bots.
A diferença de 1.520 dias em dragnet-org/dragnet vem de um humano que enviou uma branch chamada mp/py3.10 — um port de Python 3.10 que nunca foi mergeado. Alguém tentou levar isso adiante e parou. Isso não é ruído automatizado inflando timestamp; é um registro visível e datado de uma tentativa de resgate que falhou. Discursivamente, é talvez o sinal mais útil de todo o dataset, e a moldura “foi o dependabot” apagaria isso.
Mistos, e maiores do que qualquer uma das duas explicações isoladas: dois. crawlab-team/crawlab tem 12.250 estrelas — o segundo repositório com mais estrelas da amostra — e uma diferença de 488 dias em main. Seu feed contém branches do dependabot e 24 pushes pós-commit feitos por humanos, todos para develop e test. Quem lê o cabeçalho vê fevereiro de 2026 e assume saúde; quem lê main vê outubro de 2024 e assume morte. Os dois estão errados. O desenvolvimento foi para fora da branch padrão, algo que projetos fazem e que o resumo do GitHub não consegue expressar. sjdirect/abot é o outro caso misto: o push que definiu seu pushed_at principal realmente veio do dependabot, mas um humano enviou upgrade1 em 2024, por isso ele sai do conjunto filtrado mais adiante.
Rhizome-Conifer/conifer é o caso ambíguo, e eu inicialmente o interpretei mal. A branch padrão é main, não master, e main está parada desde 2023-10-12 — o único evento de main no feed é a criação da branch em janeiro de 2025, consistente com uma renomeação. Enquanto isso, uma única conta fez push em conifer-twilight e twilight/read-only em 2026-07-22, cinco dias antes da data de referência. Isso é atividade humana real, mas “desenvolvido ativamente” é mais do que os refs deixam provar: um contribuinte, em branches chamadas read-only, combina tanto com um encerramento gerenciado quanto com desenvolvimento contínuo. O que se pode afirmar é mais estreito, mas ainda vale dizer: a diferença de 1.013 dias não é ruído de bot, e também não é prova de abandono.
Desconhecido: sete. php-html-parser, simhash-py, internetarchive/wayback, boilerpipe, waybackurls, wpull e crawler4j têm uma diferença verificada e um feed de atividade que volta vazio.
A explicação tentadora é retenção — o feed de atividade do GitHub não volta ao infinito. O cache refuta isso para a maioria. O evento mais antigo em todas essas 123 respostas é 2023-03-10, e cinco dos sete têm pushed_at confortavelmente dentro dessa janela: php-html-parser 2024-08-09, wpull 2024-04-29, waybackurls 2024-05-01, internetarchive/wayback 2024-03-01, simhash-py 2023-05-15. O que quer que tenha movido esses timestamps deveria aparecer no feed e não apareceu. A retenção explica apenas boilerpipe (2018) e crawler4j (2021).
Então a formulação honesta é mais estreita do que uma explicação elegante: para sete repositórios, a diferença é um fato verificado e sua causa não foi estabelecida — o endpoint não retornou nada, e para cinco deles eu não consigo dizer por quê. “Foi o dependabot” é uma suposição para todos os sete.
Somando os 14 repositórios sinalizados:
Causa do pushed_at inflado | Repositórios | Quais, e com base em quê |
|---|---|---|
| Confirmado como bot | 3 | scrapinghub/splash (4 de 4 eventos pós-commit em dependabot/pip/*), geziyor/geziyor (5 de 5 em dependabot/go_modules/*), apache/any23 (16 de 16 em dependabot/maven/*) — any23 está arquivado, restando dois que também satisfazem todas as outras condições |
| Misto, bot e humano | 2 | crawlab-team/crawlab (branches do dependabot mais 24 pushes pós-commit de humanos, todos para develop e test), sjdirect/abot (o push que definiu seu pushed_at principal realmente foi do dependabot, mas um humano enviou upgrade1 em 2024) |
| Totalmente errado — trabalho humano, zero branches de bot | 2 | dragnet-org/dragnet (3 eventos pós-commit, 0 em branch de bot) — um humano enviando mp/py3.10, um port de Python 3.10 não mergeado. Rhizome-Conifer/conifer (30 eventos pós-commit, 0 em branch de bot) — uma única conta enviando conifer-twilight e twilight/read-only em 2026-07-22. Se conifer está abandonado continua ambíguo, como dito acima; o que não é ambíguo é que nenhum bot inflou seu pushed_at |
| Não estabelecido — feed de atividade vazio | 7 | php-html-parser, simhash-py, internetarchive/wayback, boilerpipe, waybackurls, wpull, crawler4j |
As linhas somam 14. Elas classificam o que moveu pushed_at; não estabelecem, por si só, se um projeto foi abandonado.
O que sobrevive ao filtro completo — e o que “sobrevive” significa
A alegação original exige quatro coisas ao mesmo tempo: estar defasado há mais de um ano, ter pushed_at inflado em mais de 180 dias, não estar arquivado e não haver sinal de que a inflação veio de trabalho humano. Nove dos 35 candidatos passam pelas quatro, listados aqui junto com as duas exclusões mais importantes:
| Repositório | Passa nas quatro? | Evidência positiva de que bots inflaram o valor |
|---|---|---|
splash | sim | sim — 4 de 4 eventos pós-commit em dependabot/pip/* |
waybackurls | sim | nenhuma em ambos os sentidos |
crawler4j | sim | nenhuma em ambos os sentidos |
geziyor | sim | sim — 5 de 5 em dependabot/go_modules/* |
php-html-parser | sim | nenhuma em ambos os sentidos |
boilerpipe | sim | nenhuma em ambos os sentidos |
wpull | sim | nenhuma em ambos os sentidos |
internetarchive/wayback | sim | nenhuma em ambos os sentidos |
simhash-py | sim | nenhuma em ambos os sentidos |
any23 | não — arquivado | sim — 16 de 16 em dependabot/maven/*, a confirmação mais forte de toda a auditoria |
abot | não — seu histórico contém um push humano (upgrade1, 2024) | misto — o push que definiu seu pushed_at principal realmente foi do dependabot |
Esse número precisa de uma qualificação que o filtro não consegue carregar. Só dois dos nove — splash e geziyor — têm evidência positiva de que bots inflaram o valor. Os outros sete passam pela quarta condição por não haver evidência em nenhum dos dois sentidos. São casos em que a alegação sobrevive, não casos que a confirmam. E a confirmação mais forte de toda a auditoria, any23 com 16 de 16 eventos do dependabot, fica de fora porque o repositório está arquivado.
Observe também que abot, o caso de 1.802 dias, não está entre os nove. O histórico dele contém um push humano, então ele falha na quarta condição — a ilusão mais dramática do dataset não é um exemplo limpo do mecanismo que ilustra.
Em 21 de 35, o GitHub mostrou a defasagem de forma direta
Aqui está o achado que mais enfraqueceu minha tese. Quatorze repositórios têm diferença exatamente zero, e outros sete ficam abaixo de 180 dias. Em 21 dos 35 candidatos, pushed_at é o último commit da branch padrão. O GitHub não está escondendo nada.
Incluindo alguns dos casos mais mortos da amostra:
| Repositório | Estrelas | Defasagem (dias) | Diferença |
|---|---|---|---|
Janpot/microdata-node | 57 | 1.866 | 0 |
1e0ng/simhash | 1.037 | 1.606 | 21 |
ekzhu/SetSimilaritySearch | 603 | 1.384 | 0 |
GerbenJavado/LinkFinder | 4.431 | 834 | 0 |
hakluke/hakrawler | 5.099 | 582 | 0 |
lavague-ai/LaVague | 6.388 | 551 | 0 |
my8100/scrapydweb | 3.411 | 522 | 0 |
getomni-ai/zerox | 12.258 | 432 | 0 |
scrapinghub/frontera | 1.332 | 415 | 0 |
BuilderIO/gpt-crawler | 22.374 | 384 | 0 |
BuilderIO/gpt-crawler tem 22.374 estrelas e seu cabeçalho diz a mesma coisa desde 2025-07-07. Nada está oculto, e o volume de instalações continua.
Isso força a tese a ficar mais estreita: o GitHub obscurece a defasagem em uma minoria dos casos e, na maioria, a mostra claramente enquanto as instalações continuam mesmo assim. Por que continuam é algo que estes dados não conseguem responder — os números aqui contam instalações, não decisões. Mas nenhuma mudança de interface resolve o segundo grupo, que é o maior.
A atividade do repositório e o artefato publicado podem divergir
A linha mais marcante do dataset rompe completamente o enquadramento.
codelucas/newspaper — 15.126 estrelas — está ativo. Seu último commit na branch padrão é de 2026-07-21, em relação à data de referência de 2026-07-27, e foi feito pelo maintainer. Todas as checagens no nível do repositório passam.
O pacote que todo mundo instala é newspaper3k 0.2.8, publicado em 2018-09-28. Isso significa 2.858 dias de idade, e ele recebe 813.513 downloads por mês.
A branch padrão está atualizada, enquanto o artefato no PyPI não é lançado desde 2018. Isso prova uma lacuna de release, não o motivo de o pacote não ter sido lançado nem se o pipeline está quebrado. É o tipo de risco que uma checagem de manutenção apenas no repositório deixaria passar, porque o artefato do registry é o que normalmente roda depois de pip install newspaper3k.
Quando você passa a olhar para pacotes, e não apenas para repositórios, o padrão aparece em todo lugar. Entre os 17 pacotes cuja atribuição ao repositório foi verificada, 16 tiveram o último lançamento há mais de um ano, e esses 16 respondem por cerca de 2,28 milhões de instalações por mês de um total de 2,30 milhões:
| Pacote | Instalações/mês | Última publicação | Idade do pacote (dias) |
|---|---|---|---|
newspaper3k | 813.513 | 2018-09-28 | 2.858 |
tls-client | 790.305 | 2024-02-02 | 905 |
simhash | 317.615 | 2022-03-03 | 1.606 |
microdata-node | 204.025 | 2020-05-11 | 2.267 |
@modelcontextprotocol/server-puppeteer | 127.232 | 2025-05-12 | 440 |
extract-thinker | 10.927 | 2025-06-09 | 412 |
SetSimilaritySearch | 7.984 | 2022-10-11 | 1.384 |
frontera | 4.709 | 2019-04-05 | 2.669 |
zerox | 3.303 | 2025-05-20 | 432 |
scrapydweb | 1.163 | 2025-02-16 | 525 |
lavague | 606 | 2024-08-05 | 720 |
splash | 333 | 2020-06-16 | 2.231 |
dragnet | 213 | 2019-04-16 | 2.658 |
@builder.io/gpt-crawler | 137 | 2025-01-23 | 549 |
lmnr-index | 120 | 2025-06-05 | 416 |
simhash-py | 113 | 2017-03-22 | 3.413 |
tls-client merece destaque próprio: 790.305 instalações por mês a partir de um repositório sem atividade há 905 dias, em uma categoria na qual ficar atualizado é justamente a função principal. O comportamento de TLS dos navegadores muda; uma biblioteca que parou de acompanhar isso no início de 2024 está operando com premissas de início de 2024.
Duas ressalvas sobre essa tabela. Os números de download dos registries incluem execuções de CI e mirrors, e não removem duplicatas, então medem volume de instalação, não de pessoas. E as janelas móveis não têm a mesma data final — no npm ela fecha em 2026-07-24, enquanto no pypistats ela é relativa ao momento da coleta — então o total é a soma de meses ligeiramente deslocados e deve ser lido como “cerca de 2,28 milhões”, não no dígito exato.
A colisão de nomes que vale conhecer
internetarchive/wayback é o OpenWayback em Java, sem atividade há 1.916 dias. wayback no PyPI é um projeto completamente diferente — edgi-govdata-archiving/wayback — e está saudável, com a versão 0.5.1 publicada em 2026-06-19, cinco semanas antes da data de referência. Mesmo nome, condição oposta, nenhuma relação. Esta foi uma das seis atribuições rejeitadas, e é a que mais provavelmente pegaria um usuário real: pesquisar pelo nome traz os dois resultados, e nada em nenhuma das páginas diz qual deles você encontrou.
Arquivado, descontinuado e ainda instalado 127.232 vezes por mês
Seis repositórios da amostra têm archived: true, e o GitHub mostra isso como um banner em largura total. Minha primeira leitura foi que isso provava que as pessoas ignoram avisos em letras grandes. O cache mostra que a história é pior do que isso.
Referência oficial: documentação da API de contagem de downloads do npm.
Referência oficial: documentação de descontinuação do npm.
@modelcontextprotocol/server-puppeteer recebe 127.232 instalações por mês a partir de modelcontextprotocol/servers-archived. Mas o campo repository no npm é null — não existe link da página do pacote de volta para o repositório, então o banner não é algo que o instalador simplesmente ignorou. A maioria das pessoas que baixa esse pacote nem sequer tinha um caminho visível até o repositório.
O que o npm de fato publica é a descontinuação. A versão mais recente do pacote traz deprecated: "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info." — mensagem que o npm imprime no terminal durante a instalação. Ou seja, o aviso é entregue no lugar em que o usuário realmente está, e ainda assim 127.232 instalações por mês continuam acontecendo. Isso é um achado mais forte do que o do banner e aponta para outro lugar: o sinal não está ausente, ele está chegando no meio de uma enxurrada de saída da instalação que ninguém é obrigado a ler.
browserbase/mcp-server-browserbase mostra como é um desligamento limpo: o commit final da branch padrão, em 2026-07-20, é literalmente “Mark repository as archived and unmaintained (#198)”. Os mantenedores anunciaram, dataram e sinalizaram isso na API. Seus 20.389 downloads merecem leitura cuidadosa, porém — a janela do npm vai de 2026-06-25 a 2026-07-24, então 26 desses 30 dias precedem o commit de arquivamento. Esse volume é majoritariamente demanda anterior ao anúncio, não desafio a ele. O que acontece depois realmente não dá para saber a partir deste instantâneo, e eu gostaria de ver uma nova leitura daqui a um mês antes de afirmar qualquer coisa.
57 estrelas, 204.025 instalações por mês
Janpot/microdata-node tem 57 estrelas e recebe 204.025 downloads por mês a partir de uma release de 2020-05-11.
Com 57 estrelas, microdata-node tem pouca visibilidade de repositório diante do volume no registry. A proporção de 3.579 instalações por estrela é compatível com uso transitivo, repetição em CI, mirrors ou consumo direto por máquinas. Esta auditoria não buscou grafos de dependência e, portanto, não pode escolher entre essas explicações.
A linha serve para sinalizar exposição indireta, mas provar uso transitivo exige evidência de dependências reversas ou de lockfiles, algo que esta auditoria não coletou.
Defasado não é o mesmo que quebrado
Uma auditoria honesta precisa dizer isso: nada aqui mede se alguma coisa está quebrada. Mede se há alguém em casa.
Alguns desses projetos simplesmente terminaram. SetSimilaritySearch implementa algoritmos de similaridade de conjuntos; isso não “apodrece”. simhash é um paper de 2007. O algoritmo de extração de conteúdo do boilerpipe se comporta em 2026 da mesma forma que em 2015 — seja qual for sua precisão em páginas modernas, o código não saiu debaixo de você.
O que apodrece é o que depende de um alvo em movimento:
- Automação de navegador — cada nova versão do Chrome pode quebrar tudo.
- Comportamento de cliente HTTP que imita navegadores reais — navegadores mudam, e uma biblioteca congelada para de acompanhar;
tls-cliententra aqui. - Parsers específicos de sites e regras de extração por site — cada redesign vira bug.
- Tudo o que encapsula uma API de terceiros — o fornecedor muda o schema e você descobre em produção.
- Tudo o que encapsula um LLM — depreciações de modelos mudam mais rápido do que qualquer uma dessas coisas.
Então “1.606 dias defasado” é um incêndio de cinco alarmes para uma categoria e quase irrelevante para uma biblioteca de hashing. Nenhuma quebra foi testada aqui e nenhuma afirmação nesse sentido está sendo feita; classificar suas próprias dependências pela categoria em que se encaixam custa nada e ajuda mais do que o número de defasagem sozinho.
As quatro checagens que realmente respondem à pergunta

Nenhuma delas é o cabeçalho do repositório.
| # | Checagem | Onde ler | O que ela detecta |
|---|---|---|---|
| 1 | O último commit na branch padrão | GET /repos/{owner}/{repo}/commits?sha={default_branch}&per_page=1 | O número que não é mostrado para você. |
| 2 | A última vez que o artefato foi publicado | pypi.org/pypi/{pkg}/json ou registry.npmjs.org/{pkg} → versão mais recente e data de upload | É isso que pega newspaper3k, e a checagem 1 nunca vai pegar. Enquanto estiver aí, leia também o campo deprecated do npm, que é como @modelcontextprotocol/server-puppeteer se anuncia. |
| 3 | A flag archived | Um campo na resposta do repositório, inequívoco e gratuito | Note que isso só ajuda se você conseguiu chegar ao repositório, o que pacotes com repository: null não permitem. |
| 4 | A diferença entre 1 e 2 | — (derivada das duas acima) | Um repositório com commits recentes e uma release de três anos atrás é um tipo de falha diferente de um que simplesmente está frio: significa que o mantenedor está presente, mas não está publicando. É uma decisão que deve ser tomada com os olhos abertos, não um sinal vermelho por si só. A mesma lógica vale ao contrário para crawlab: verifique se o trabalho foi para uma branch não padrão antes de tirar qualquer conclusão. |
Execute as checagens 1, 2 e 3 como triagem rápida. Depois aprofunde quando faltarem metadados do repositório, o mapeamento pacote↔repositório for ambíguo, a atividade tiver migrado para uma branch não padrão ou o artefato do registry divergir do repositório. Limites de GitHub sem autenticação e latência de registry tornam inadequado prometer resposta em um segundo.
Se uma checagem mostrar algo frio em uma categoria que muda rápido, as alternativas mantidas nessa área estão documentadas nos nossos próprios testes: Trafilatura para a extração de conteúdo que dragnet e boilerpipe costumavam fazer, Scrapy ou Crawlee para frameworks de crawling, Crawl4AI e Firecrawl para extração orientada por LLM, e Scrapling quando resiliência importa. Nosso pilar de scrapers open source acompanha o conjunto mais amplo. Essas são análises de primeira mão; faça as quatro checagens por conta própria antes de confiar em qualquer recomendação, inclusive nas nossas.
Limites destes dados
- Seleção da amostra. Escolhida manualmente por suspeita de abandono. Não é possível inferir taxas do ecossistema a partir dela.
- Sem teste de quebra. Nenhuma dessas 35 ferramentas foi executada contra um site ao vivo. Defasagem é sinal de manutenção, não veredito funcional.
- Contagens de download incluem máquinas. CI, mirrors, sem deduplicação e com janelas que não compartilham a mesma data final. Volume de instalação, não usuários, e não decisões.
- Sete causas desconhecidas continuam desconhecidas. O feed de atividade não retornou nada, e para cinco dos sete a retenção não explica isso. Deixar a célula vazia é melhor do que preenchê-la com o palpite popular.
staleness_daysusa datas do committer. Histórico reescrito ou retrodatado distorceria o cálculo. Nada disso foi detectado, o que não é o mesmo que dizer que não existe.- Uma única data de referência. 2026-07-27. Vários desses repositórios terão mudado quando você ler isto —
newspaper, em especial, faz commits com frequência. Refaça as quatro checagens; não cite minhas datas.
Onde um serviço gerenciado muda a equação
Cada checagem aqui existe porque, com uma biblioteca self-hosted, a defasagem é sua. Se um cliente HTTP congelado para de se comportar como um navegador atual, isso vira um incidente seu, na hora em que aparecer.
Nota do autor: Thunderbit é nosso produto gerenciado de scraping. Um serviço gerenciado transfere parte da responsabilidade de manutenção para o fornecedor, mas cobertura, tempo de resposta, lock-in e continuidade do fornecedor passam a fazer parte do modelo de risco. O Thunderbit não foi avaliado nesta auditoria de repositórios.
A troca honesta é esta: você abre mão de ler o código, fixar uma versão e corrigir o problema sozinho às 2 da manhã. Para uma equipe que já mantém scrapers, o caminho open source muitas vezes é o mais adequado — e as quatro checagens são a forma de transformar isso em decisão, não em suposição.
Experimente o Thunderbit para extração de dados da web
Resumo curto
Eu montei uma lista para provar que o GitHub esconde o abandono. A ilusão é real em 14 de 35 repositórios e espetacular em um caso: sjdirect/abot mostra um push na semana passada contra uma branch padrão congelada desde 2021, uma diferença de 1.802 dias.
Mas o mecanismo é mais estreito do que a história sugere. Nove repositórios passam por todas as condições exigidas pela alegação, e apenas dois desses nove — splash e geziyor — têm evidência positiva de que bots inflaram o número; o restante passa por ausência de evidência. Dois repositórios sinalizados mostram humanos tentando e falhando em reviver um projeto. Um deles, crawlab, tem 12.250 estrelas e simplesmente transferiu o desenvolvimento para develop. Em sete, o feed de atividade veio vazio e a retenção não explica cinco desses casos, então a causa não está estabelecida, em vez de ser presumida. E em 21 dos 35 repositórios, o GitHub reportou a defasagem com precisão.
O pior caso do dataset passa por todas as checagens no nível do repositório. codelucas/newspaper recebeu commit em 2026-07-21; newspaper3k, publicado pela última vez em 2018-09-28, saiu 813.513 vezes naquele mês. Na amostra inteira, 16 pacotes com releases com mais de um ano respondem por cerca de 2,28 milhões de instalações por mês.
Verifique a data do último commit da branch padrão, a data de publicação no registry, a flag de arquivamento e o campo de depreciação do npm como triagem inicial. Resolva a atribuição pacote↔repositório e o desenvolvimento fora da branch padrão antes de chegar a qualquer conclusão.
Experimente o Thunderbit para extração de dados da web Get Started Free
FAQs
O que é pushed_at e por que isso não significa “última atualização”?
pushed_at é o campo da API do GitHub por trás do timestamp de atividade exibido na página do repositório, e ele é atualizado quando qualquer coisa recebe push em qualquer branch. O commit mais recente da branch padrão é apenas um dos sinais de manutenção do repositório, enquanto gerenciadores de pacotes normalmente instalam artefatos do registry ou versões resolvidas de módulos. Nesta auditoria, 14 dos 35 repositórios mostraram uma diferença superior a 180 dias entre esses dois timestamps do GitHub.
É sempre o dependabot inflando esse timestamp?
Não, e essa acabou sendo a parte mais fraca da história popular. Contando apenas eventos que aconteceram depois do último commit da branch padrão, bots foram confirmados em 3 dos 14 repositórios sinalizados (splash 4 de 4, geziyor 5 de 5, any23 16 de 16). Em 2 casos isso está simplesmente errado: a diferença em dragnet vem de um humano enviando um port de Python 3.10 não mergeado. Em mais dois casos há mistura, incluindo crawlab, onde 24 pushes humanos foram para develop e test enquanto main ficou parada. E em 7 o feed de atividade não retornou nada, então a causa não está estabelecida — a retenção explica apenas dois desses sete.
Um repositório antigo quer dizer que a ferramenta está quebrada?
Não com base nesta evidência — nada aqui foi executado contra um site ao vivo. Defasagem importa de forma diferente conforme a velocidade do alvo: automação de navegador, clientes HTTP que imitam comportamento de navegador, parsers específicos por site e wrappers de API/LLM envelhecem rápido, enquanto bibliotecas algorítmicas como SetSimilaritySearch ou simhash podem ter anos de idade e continuar totalmente adequadas. tls-client é o caso mais contundente da amostra, com 790.305 instalações por mês a partir de um repositório sem atividade há 905 dias.
Como um repositório pode estar ativo e o pacote ainda assim estar morto?
Esse é codelucas/newspaper, e é a coisa mais importante encontrada por esta auditoria. A branch padrão recebeu commit em 2026-07-21, dias antes da data de referência, mas newspaper3k no PyPI teve seu último lançamento, 0.2.8 em 2018-09-28 — 2.858 dias — e ainda recebe 813.513 downloads por mês. As checagens no nível do repositório passam todas; o artefato que você instala tem oito anos. Sempre verifique a data da última publicação no registry separadamente do log de commits.
Repositórios arquivados resolvem isso? O GitHub mostra um banner.
Não de forma confiável, e @modelcontextprotocol/server-puppeteer mostra o porquê. O campo repository no npm é null, então não há link do pacote para o repositório arquivado e nenhum banner para ignorar. O que o npm realmente entrega é a string deprecated do pacote — “Package no longer supported” — exibida no momento da instalação, e 127.232 instalações por mês continuam acontecendo apesar disso. browserbase/mcp-server-browserbase anunciou o encerramento corretamente no commit final; seus 20.389 downloads ocorreram em sua maioria antes desse commit, então dizem pouco em qualquer sentido.
Como eu verifico rapidamente minhas próprias dependências?
Comece pela data do último commit da branch padrão, pela data da versão/upload no registry, pelo campo de depreciação do npm e pela flag de arquivamento do repositório. Depois confirme a atribuição pacote↔repositório, examine branches não padrão quando a atividade divergir e use grafos de dependência ou lockfiles antes de chamar a exposição de transitiva. Colisões de nome, como os projetos não relacionados wayback em Java e no PyPI, tornam essa etapa de aprofundamento necessária.


