Como o Baseline ajuda a usar menos JavaScript
A distância entre “você precisa de uma biblioteca para isso” e “o browser já faz isso” continua diminuindo. Este é um guia prático para auditar as dependências de um projeto e encontrar o que a plataforma web já consegue resolver sozinha, ou seja, como o Baseline ajuda a usar menos JavaScript.
A maioria das pessoas instala uma dependência uma vez e nunca mais olha para ela. Ela faz o trabalho, os testes passam e a vida segue. Mas a plataforma web também continua avançando, e um número surpreendente das bibliotecas que estão hoje no package.json já vem embutido no browser.
Em uma aplicação JavaScript de porte médio, é comum encontrar algo entre 60 KB e 90 KB (minificados e com gzip) de dependências que a plataforma já resolve sozinha.
Formatação de datas e números, requisições HTTP, modais, tooltips, clonagem profunda, agrupamento de arrays: tudo isso eram lacunas reais alguns anos atrás. Mas as coisas já evoluíram bastante.
O motivo de essas bibliotecas continuarem por ali não é preguiça. É que a maioria dos times não reaudita suas dependências em uma cadência de Baseline, ou simplesmente não faz ideia da velocidade com que os browsers estão lançando recursos hoje em dia.
Todo mundo roda npm audit para checar segurança, mas “Essa biblioteca ainda faz algo que o browser não faz?” é uma pergunta que quase nunca aparece. Então, as bibliotecas ficam.
Neste artigo, essa auditoria será feita passo a passo. Em vez de percorrer dependência por dependência, o trabalho será feito em grupos, porque os ganhos costumam vir juntos.
A conta do bundle será feita. Um pequeno framework de decisão reutilizável será construído. E os casos em que a plataforma ainda deixa a desejar serão tratados com honestidade. No fim, o resultado é um processo repetível para rodar no próprio package.json.

O que “Baseline” realmente significa
Antes de começar a apagar coisas, vale uma recapitulação rápida do que é Baseline. Fique à vontade para pular esta seção se o conceito já for familiar.
Baseline (às vezes traduzido como “padrão de referência”) é um projeto do WebDX Community Group que informa, em termos simples, o quão seguro é usar um recurso da web nos principais browsers (Chrome, Edge, Firefox e Safari).
Um recurso pode estar em um de 3 estados:
- Limited Availability (Disponibilidade Limitada). O recurso ainda não foi lançado em todos os principais motores. Não é seguro depender dele sem um fallback.
- Baseline Newly Available (Recém-Disponível). Acabou de chegar em todos os principais motores. Funciona para quem está com o browser atualizado, mas dispositivos mais antigos por aí podem ainda não tê-lo.
- Baseline Widely Available (Amplamente Disponível). Está em todos os principais motores há 30 meses (2,5 anos). Nesse ponto, dá para usá-lo com tranquilidade.
Esse intervalo de 30 meses entre “Newly” e “Widely” importa muito nesta auditoria. Um recurso Widely Available normalmente é algo pelo qual já se pode abrir mão de uma biblioteca à parte.
Um recurso apenas Newly Available é algo pelo qual se pode abrir mão de uma biblioteca se o padrão de visitantes do site/app for checado antes ou se houver conforto com uma pequena verificação de suporte. Ambos os casos serão tratados de forma diferente ao longo do texto.
É possível consultar qualquer recurso no webstatus.dev (toda página de referência exibe um selo Baseline logo no topo) ou programaticamente com o pacote npm web-features.
Um framework de decisão antes de apagar qualquer coisa
É tentador ler “o browser já faz isso” e sair arrancando bibliotecas. Melhor não. Uma troca que parece gratuita no papel pode quebrar silenciosamente a experiência de uma parcela dos usuários ou custar um recurso do qual havia dependência sem que ninguém percebesse.
Então, antes de descartar qualquer biblioteca, faça 3 perguntas. Elas serão reaproveitadas em cada grupo abaixo.
1. A substituição é Baseline-safe para a minha audiência?
Não “isso é Baseline” no abstrato, mas “isso é seguro para as pessoas que realmente usam a minha aplicação”. Se o recurso nativo for Widely Available, a resposta costuma ser sim. Se for apenas Newly Available, cheque a analytics ou a configuração de browserslist e veja qual fatia dos usuários ficaria de fora.
Um dashboard B2B em que todo mundo usa o browser mais recente é uma situação muito diferente de um site público com cauda longa de dispositivos Android antigos.
2. Quanto custa a troca, de fato?
Descartar uma biblioteca nem sempre é de graça. Às vezes o recurso nativo ainda não tem suporte amplo o bastante, o que leva a recorrer a um polyfill.
Se esse polyfill for mais pesado que a biblioteca removida, o bundle acabou maior, a menos que o carregamento seja condicional.
3. O recurso da plataforma cobre o meu caso de uso real?
Bibliotecas costumam fazer mais do que o recurso de plataforma com o qual se parecem. axios não é apenas fetch com parsing automático de JSON; ele tem interceptors, cancelamento de requisição e retries.
Se esses recursos estiverem em uso, uma troca direta por fetch vai deixar tudo isso para reimplementar. Verifique o que realmente é usado antes de supor que a substituição é plug and play.
Guarde essas 3 perguntas. Todo grupo abaixo é apenas isso: as mesmas perguntas aplicadas a um canto diferente das dependências.
Grupo 1: Internacionalização (a maior vitória imediata)
Este é o grupo em que normalmente se encontra o maior número de KBs empilhados sobre recursos que já são Widely Available. O browser traz uma família inteira de ferramentas de formatação sob o namespace Intl, e muitas bibliotecas pequenas e populares se tornaram desnecessárias.
Eis os suspeitos de sempre e o que os substitui:
timeago.js(1 KB gz) →Intl.RelativeTimeFormatpluralize(2,3 KB gz) →Intl.PluralRulesnumeral(3,9 KB gz) →Intl.NumberFormathumanize-duration(6,6 KB gz) →Intl.DurationFormat- helpers de junção de listas →
Intl.ListFormat
Vamos passar por alguns deles.
Tempo relativo
timeago.js existe para transformar um timestamp em “3 horas atrás”. Intl.RelativeTimeFormat faz a mesma coisa e é Baseline Widely Available.
const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
rtf.format(-1, "day"); // "yesterday"rtf.format(3, "hour"); // "in 3 hours"rtf.format(-2, "week"); // "2 weeks ago"A opção numeric: "auto" é o toque especial aqui: ela devolve “yesterday” em vez de “1 day ago” quando o idioma tem uma palavra para isso. Você passa um número e uma unidade e recebe de volta uma string localizada.
Talvez fique a dúvida sobre a única coisa que o timeago.js faz e o trecho acima não: escolher a unidade automaticamente. Dada uma data, o timeago.js decide se deve dizer “segundos” ou “dias”. Intl.RelativeTimeFormat espera que essa parte seja feita por você.
São algumas poucas linhas de aritmética (calcular a diferença e achar a maior unidade que cabe) e, uma vez escrito esse helper, a biblioteca deixa de ser necessária.
Números, moedas e listas
Intl.NumberFormat cobre a maior parte do que as bibliotecas de formatação numérica fazem: separadores de milhar, moeda, porcentagem e notação compacta.
new Intl.NumberFormat("en-US").format(1234567.89);// "1,234,567.89"
new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format( 1234.5,);// "$1,234.50"
new Intl.NumberFormat("en", { notation: "compact" }).format(1200000);// "1.2M"E Intl.ListFormat, Widely Available, resolve o problema de “juntar um array em uma frase”, incluindo a vírgula de Oxford, que é o tipo de coisa para a qual as pessoas escrevem funções auxiliares cheias de firulas:
const lf = new Intl.ListFormat("en", { style: "long", type: "conjunction" });
lf.format(["Alice", "Bob", "Carol"]);// "Alice, Bob, and Carol"A única ressalva: durações
humanize-duration transforma um número de milissegundos em “1 hora, 30 minutos”. O equivalente da plataforma é Intl.DurationFormat:
const df = new Intl.DurationFormat("en", { style: "long" });
df.format({ hours: 1, minutes: 30 });// "1 hour, 30 minutes"Vale ter em mente que Intl.DurationFormat é Baseline Newly available no momento em que este texto foi publicado, não Widely Available. Ele chegou a todos os principais motores em março de 2025 e está a caminho de se tornar Widely Available em 2027.
Ou seja, esse aqui reprova na pergunta 1 para aplicações de audiência ampla, a menos que o tráfego seja checado antes ou que haja um fallback.
Para uma ferramenta interna rodando em browsers modernos, já está de bom tamanho hoje. Para um site público com dispositivos antigos, espere mais um ano ou proteja o uso com uma verificação de recurso.
A conta deste grupo
Se a aplicação usa o conjunto completo (humanize-duration, timeago.js, pluralize, numeral), isso dá cerca de 14 KB com gzip de dependências, a maior parte substituível agora mesmo por APIs Widely Available. O grupo de internacionalização costuma ser a vitória mais fácil de toda a auditoria.
Grupo 2: Clientes HTTP
Este grupo é mais cheio de nuances, então é um bom lugar para desacelerar.
As bibliotecas HTTP que as pessoas usam no browser são axios (17 KB gz) e superagent (19 KB gz). Para a maioria das requisições, fetch mais AbortController cobrem o necessário, e ambos são Widely Available.
Um GET básico fica assim:
// axiosconst { data } = await axios.get("/api/users");
// fetchconst res = await fetch("/api/users");const data = await res.json();A linha extra (res.json()) é o fetch sendo explícito onde o axios era implícito. Esse é o padrão em todo este grupo: o fetch faz menos por você por padrão, e cabe a você decidir se quer as coisas que ele deixa de fora.
Timeouts
axios tem uma opção timeout. fetch tem AbortSignal.timeout():
const res = await fetch("/api/users", { signal: AbortSignal.timeout(5000), // aborta depois de 5 segundos});Onde o fetch não substitui o axios
É aqui que a pergunta 3 faz a maior parte do trabalho, então vale ser específico sobre as lacunas:
fetchnão rejeita em erros HTTP. Um404ou500é uma promise resolvida, não uma rejeição. É preciso checarres.okmanualmente.axiosrejeita em qualquer status fora da faixa 2xx.- Sem interceptors. Se houver dependência dos interceptors do
axiospara anexar tokens de autenticação ou tratar 401 em um único lugar, ofetchnão tem equivalente. Seria preciso envolver ofetchem uma função ou classe própria para obter o mesmo comportamento. - Sem retries automáticos.
axios(com um plugin) consegue repetir requisições que falharam. Comfetch, esse código é por sua conta. - Sem progresso de upload. O
fetchainda não consegue reportar progresso de upload de forma nativa. Se houver um uploader de arquivos com barra de progresso, esse é um motivo real para manter uma biblioteca.
Nenhum desses pontos é difícil de reconstruir, e a maioria das aplicações usa apenas um ou dois deles. Mas este é exatamente o tipo de grupo em que não se deve fazer um localizar-e-substituir cego.
Olhe primeiro como o cliente HTTP é realmente usado. Se forem apenas GETs e POSTs simples, trocar o axios por um wrapper enxuto de fetch economiza cerca de 17 KB com gzip.
Grupo 3: Primitivos de UI
Este grupo tem algumas das trocas mais satisfatórias, porque os recursos da plataforma não apenas empatam com as bibliotecas: eles costumam ser mais acessíveis do que aquilo que os times entregam na mão.
As bibliotecas aqui são as de modal (algo como a11y-dialog, 1,8 KB gz), as de tooltip e popover (tippy.js, 14 KB gz, que embute o Popper para posicionamento), focus-trap (6,6 KB gz) e body-scroll-lock (1,3 KB gz).
Elas são substituídas por três recursos da plataforma: o elemento <dialog>, a Popover API e o anchor positioning do CSS.
O elemento <dialog>
Uma quantidade enorme de código relacionado a modais existe para resolver problemas de acessibilidade: prender o foco dentro do modal, fechar com Escape, devolver o foco ao elemento anterior quando o diálogo é fechado e renderizar acima de tudo. O elemento <dialog>, Widely Available, faz tudo isso sozinho.
<dialog id="confirm"> <form method="dialog"> <p>Delete this file?</p> <button value="cancel">Cancel</button> <button value="delete">Delete</button> </form></dialog>const dialog = document.querySelector("#confirm");
dialog.showModal(); // o foco entra, o fundo fica inerte, Escape fecha
dialog.addEventListener("close", () => { console.log(dialog.returnValue); // "cancel" ou "delete"});Chamar showModal() faz o trabalho pelo qual o focus-trap foi instalado: o foco entra no diálogo, o resto da página se torna inerte (impedindo sair dele com Tab), Escape fecha e o foco volta ao elemento que abriu o modal.
O dialog é renderizado na Top layer do browser, então não é preciso brigar com z-index. Também há um pseudo-elemento ::backdrop para estilizar o overlay.
Esse único elemento pode substituir a biblioteca de modal e o focus-trap. A única peça que ele não resolve sozinho é travar a rolagem do fundo, que era a função do body-scroll-lock. Isso agora é uma linha de CSS:
body:has(dialog:modal) { overflow: hidden;}Talvez tenha ficado a dúvida sobre por que usar dialog:modal em vez de dialog[open]. O motivo é que o atributo open é definido assim que show() é chamado. Nesse momento, porém, o diálogo ainda não é de fato modal, então travar a rolagem seria precipitado.
A pseudo-classe :modal só é verdadeira quando o diálogo é realmente modal, o que acontece ao chamar showModal(). Se a sintaxe do :has() for novidade, vale conhecê-la: é ela que permite estilizar o body a partir de um filho.
Ou seja: 3 bibliotecas se reduzem a um elemento e uma regra de CSS.
Popover API e anchor positioning
Para coisas que não são modais completos (menus dropdown, tooltips, os pequenos painéis flutuantes que o tippy.js resolve), a Popover API entrega comportamento de light dismiss, renderização na top layer e fechamento com Escape sem nenhum JavaScript:
<button popovertarget="menu" id="options">Options</button>
<div id="menu" popover> <!-- conteúdo do menu --></div>Clicar no botão alterna o popover. Clicar fora dele o fecha. É Baseline Newly Available (desde janeiro de 2025).
A outra metade do que uma biblioteca de tooltip faz é posicionamento: manter o elemento flutuante grudado ao seu gatilho e virá-lo de lado quando ele estouraria a viewport.
É disso que o Popper (embutido no tippy.js) cuida, e agora existe um recurso de CSS chamado anchor positioning para isso. Abaixo, ele prende o mesmo popover #menu logo abaixo do botão que o dispara:
#options { anchor-name: --trigger;}
.tooltip { position-anchor: --trigger; position-area: top; margin: 0;}O anchor positioning é o recurso mais recente deste artigo. Ele se tornou Baseline Newly Available em janeiro de 2026, quando o Firefox 147 o lançou (o Chrome já o tinha desde a versão 125, e o Safari desde a versão 26).
Justamente por ser tão recente, é um caso claro da pergunta 1: ótimo para audiências modernas, mas cheque o tráfego antes. Leve em conta, também, que algumas das partes mais avançadas (como os fallbacks de position-try) têm suporte irregular entre versões. Mantenha um fallback sensato para browsers antigos.
Entre <dialog>, Popover API e anchor positioning, o grupo de primitivos de UI (biblioteca de tooltip, biblioteca de modal, focus-trap e body-scroll-lock) soma aproximadamente 24 KB com gzip, e o resultado final tem padrões de acessibilidade melhores do que a maioria das soluções feitas à mão.
Grupo 4: Utilitários do Lodash
O Lodash raramente é importado por inteiro hoje em dia, mas suas funções individuais aparecem em todo lugar, seja como o pacote completo lodash (25 KB gz), seja como instalações avulsas do tipo lodash.clonedeep e lodash.groupby. Várias das mais comuns já têm equivalentes diretos na plataforma.
Agrupamento
lodash.groupby reorganiza um array em um objeto indexado por alguma propriedade. Object.groupBy faz exatamente isso:
const products = [ { name: "Apple", category: "fruit" }, { name: "Carrot", category: "vegetable" }, { name: "Banana", category: "fruit" },];
const grouped = Object.groupBy(products, (product) => product.category);// {// fruit: [{ name: "Apple", ... }, { name: "Banana", ... }],// vegetable: [{ name: "Carrot", ... }],// }Também existe Map.groupBy para quando se quer um Map em vez de um objeto simples (útil quando as chaves não são strings). Ambos são Baseline Newly Available, desde março de 2024, e estão a caminho de se tornarem Widely Available no fim de 2026.
Clonagem profunda
lodash.clonedeep faz uma cópia profunda de um objeto. structuredClone é a versão da plataforma, e é Widely Available:
const original = { user: { name: "Sam", roles: ["admin"] } };
const copy = structuredClone(original);copy.user.roles.push("editor");
original.user.roles; // ["admin"] (inalterado)structuredClone dá conta dos casos complicados que derrubam o JSON.parse(JSON.stringify(...)): ele clona corretamente Date, Map, Set, ArrayBuffer e referências circulares.
O limite a conhecer (a pergunta 3 de novo) é que ele não consegue clonar funções, nós do DOM ou instâncias de classe. Em funções, ele lança erro; em instâncias de classe, descarta o prototype. Para dados simples, que é o que a maioria das pessoas clona profundamente, é uma substituição limpa.
Operações com Set
Se alguma vez você já trouxe um helper do Lodash para union, intersection ou difference, o objeto Set agora tem tudo isso embutido. Esses métodos são Baseline Newly Available desde junho de 2024:
const admins = new Set(["sam", "alex", "jo"]);const editors = new Set(["alex", "kim"]);
admins.intersection(editors); // Set { "alex" }admins.union(editors); // Set { "sam", "alex", "jo", "kim" }admins.difference(editors); // Set { "sam", "jo" }O conjunto completo de métodos é union, intersection, difference, symmetricDifference, isSubsetOf, isSupersetOf e isDisjointFrom.
O que vale a pena manter
Nem todo o Lodash migrou para a plataforma. debounce e throttle ainda não têm equivalente nativo, e são genuinamente úteis, então trazer apenas o lodash.debounce é razoável.
O objetivo aqui não é “apague o Lodash”, e sim “pare de entregar as partes que o browser já tem”. Descartar somente lodash.clonedeep e lodash.groupby já representa cerca de 8 KB com gzip.
E se o lodash completo estava sendo importado por causa de um punhado de funções, substituir as que a plataforma cobre pode permitir removê-lo por inteiro.
É a mesma lógica que já valia para os equivalentes nativos de JavaScript para funções da jQuery, só que uma geração de bibliotecas depois.
Grupo 5: Temporal, um estudo de caso sobre ainda não descartar uma biblioteca
Todos os grupos até aqui terminaram em “pode ir, descarte”. Este é o oposto, e é justamente por isso que vale incluí-lo: ele mostra o framework dizendo para esperar.
O Temporal é a tão esperada substituição do Date do JavaScript, e é uma API genuinamente melhor: objetos imutáveis, tratamento sensato de fusos horários e nada de índices de mês começando em zero. Ele alcançou o Stage 4 do TC39 em março de 2026 e faz parte da especificação ES2026.
O Firefox o lançou na versão 139 (em 2025), e o Chrome, na versão 144 (janeiro de 2026). O Safari ainda não o lançou em uma versão estável: ele está no Safari Technology Preview, com suporte estável esperado para mais adiante em 2026.
Se o Temporal for novidade, vale conferir o Temporal Cheatsheet para uma visão rápida da API e uma comparação com o Date.
Só que o Temporal não é Baseline. Ele ainda está em Limited Availability (disponibilidade limitada), porque quem usa Safari não o tem. Para usá-lo em todos os browsers hoje, é preciso um polyfill, e é aqui que a conta vira contra você.
O polyfill oficial @js-temporal/polyfill tem cerca de 44 KB com gzip. Existe um polyfill menor que internamente não depende de BigInt e pesa 19 KB com gzip. Uma biblioteca de datas leve, como o dayjs, tem cerca de 3 KB com gzip.
Ou seja: trocar o dayjs pelo Temporal mais o polyfill agora não economiza 3 KB, mas adiciona aproximadamente 41 KB ao bundle, a não ser que o polyfill possa ser carregado condicionalmente.
Passando pelo framework:
- Pergunta 1 (audiência). Temporal não é Baseline. Para uma audiência ampla, isso é muita gente de fora.
- Pergunta 2 (custo). O polyfill é mais de 10x maior que a biblioteca a ser removida. A troca deixa o bundle maior.
- Pergunta 3 (lacuna de recursos). Aqui o Temporal ganha; ele faz mais que o
dayjs. Mas isso não importa enquanto as perguntas 1 e 2 estiverem reprovando.
O veredito costuma ser claro: mantenha o dayjs (ou o date-fns) por enquanto. O momento de revisitar é quando o Safari lançar o Temporal em uma versão estável e ele alcançar o Baseline.
Aí será possível usar o Temporal nativamente e carregar o polyfill condicionalmente para quem estiver em browsers antigos. Esse é um recurso para anotar e checar de novo daqui a alguns meses, não um para agir hoje.
Como rodar essa auditoria no seu próprio package.json
Os grupos acima são um mapa inicial, mas as dependências de cada projeto são as suas. Eis um processo repetível que você pode realizar.
Passo 1: liste suas dependências de produção
Comece listando o que de fato chega aos usuários:
npm ls --omit=dev --depth=0Passo 2: meça quanto cada uma custa
Para um número rápido por pacote, o Bundlephobia mostra o tamanho minificado e com gzip de qualquer pacote npm.
Para o quadro real (quanto cada dependência custa no seu bundle de verdade, depois de tree-shaking e deduplicação), rode um analisador de bundle contra o seu build. O npx source-map-explorer funciona na maioria dos bundles, e o npx vite-bundle-visualizer funciona em projetos Vite.

Passo 3: verifique o status Baseline de cada substituição
Para cada candidato, encontre o recurso da plataforma que o substituiria e cheque o status Baseline dele. O caminho mais rápido é o webstatus.dev ou o selo Baseline na página do recurso na MDN.
Passo 4: aplique as 3 perguntas
Para cada biblioteca com substituto na plataforma, volte ao framework: é Baseline-safe para a sua audiência? Quanto custa a troca? O recurso cobre a forma como a biblioteca é realmente usada?
A maior parte das decisões vai sair da pergunta 1 (checar o status do recurso contra o browserslist) e da pergunta 3 (checar o uso real).
Passo 5: troque com progressive enhancement onde for necessário
Para recursos Widely Available, troque e siga em frente. Para os Newly Available, há 2 saídas: confirmar que a audiência está em browsers modernos ou proteger o código novo com uma verificação rápida de recurso, mantendo um fallback.
É progressive enhancement aplicado a dependências — no CSS, o equivalente é o @supports:
if (typeof Intl.DurationFormat === "function") { // usa o recurso da plataforma} else { // volta para a biblioteca, ou para um formato mais simples}Assim, é possível entregar menos código para quem consegue rodá-lo, sem quebrar quem não consegue.
Conclusão
Somando os grupos, o quadro fica concreto. O grupo de internacionalização gira em torno de 14 KB com gzip, o de HTTP fica em cerca de 17 KB, os primitivos de UI somam aproximadamente 24 KB, e os utilitários do Lodash rendem 8 KB ou mais, dependendo de quanto da biblioteca estava sendo entregue.
Para uma aplicação de porte médio, isso dá algo entre 60 KB e 90 KB com gzip de dependências!
E mais ainda se o lodash completo ou várias dessas bibliotecas estavam sendo entregues de uma vez, já que os números não comprimidos são 2x-3x maiores, que é o que aparece em um analisador de bundle antes do gzip.
Não é pouca coisa: JavaScript é o recurso mais caro de uma página, e cortá-lo costuma render mais que boa parte das outras otimizações de performance.
Alguns recursos merecem atenção ao longo do próximo ano, porque vão abrir espaço para novas trocas:
- Temporal se tornando nativo. Assim que o Safari o lançar em uma versão estável e ele alcançar o Baseline, será possível descartar tanto a biblioteca de datas quanto o polyfill, transformando a regressão de hoje em um ganho real.
- Anchor positioning do CSS amadurecendo. Ele se tornou Baseline Newly Available em janeiro de 2026. Conforme envelhece rumo ao Widely Available, descartar bibliotecas de posicionamento de tooltip e popover fica mais seguro para audiências amplas.
Object.groupBye companhia cruzando para Widely Available. O lote de 2024 (agrupamento de arrays, métodos de Set) está a caminho de se tornar Widely Available no fim de 2026, o que os move de “cheque sua audiência” para “pode usar”.
Nada disso é uma faxina única. A plataforma lança recursos novos constantemente, e a distância entre “você precisa de uma biblioteca para isso” e “o browser já faz isso” continua diminuindo.
O hábito que vale construir é pequeno: uma vez por trimestre, rode a auditoria. Liste as dependências, cheque o que virou Baseline e devolva o que der.
Escolha um grupo deste artigo, abra o seu package.json e veja quanto dele o browser já faz por você.