Alguém Ainda Usa Polyfills em 2026?
Polyfills em 2026? Audite core-js, Browserslist e Babel para remover peso morto, manter Temporal e abandonar o polyfill.io.
Sim — mas quase nenhum dos que o seu bundler herdou. A abordagem de polyfill genérico que fazia sentido em 2019, enviando @babel/preset-env com useBuiltIns: 'entry' contra um target amplo no Browserslist, hoje envia peso morto para a esmagadora maioria dos usuários para suportar uma fatia de mercado de browsers que arredonda para zero. Um polyfill ainda é a ferramenta certa para uma lista curta e específica de funcionalidades genuinamente não suportadas em 2026 — e um passivo para todo o resto.
Este artigo resolve uma única decisão: se os polyfills no seu pipeline de build atual ainda justificam os bytes que ocupam. Ele identifica quais APIs são peso morto, quais ainda precisam legitimamente de um polyfill, o que o incidente de segurança na cadeia de fornecimento do polyfill.io mudou na forma como você os carrega, e os comandos exatos para auditar o que você está realmente enviando.
Principais Conclusões
- Para uma aplicação React, Vue, Svelte ou Next.js que tem como alvo browsers evergreen em 2026, o número correto de polyfills para a maioria das equipes é próximo de zero — com exceções nomeadas para Decorators, Temporal durante sua transição entre browsers, e restrições de browsers corporativos bloqueados.
Array.flat,Object.entries,Promise.allSettled,structuredClone, optional chaining, nullish coalescing efetchsão amplamente suportados em 2026; polyfillá-los envia bytes que não servem a quase nenhum usuário real.- O padrão de polyfill remoto (carregando um script do polyfill.io) está morto após o incidente de segurança na cadeia de fornecimento de 2024; Cloudflare e Fastly criaram espelhos, mas o padrão em si não é mais defensável.
- Execute
npx browserslistpara ver os browsers exatos que sua configuração tem como alvo, e depois usesource-map-explorerpara descobrir quanto peso docore-jsvocê está enviando. - A classificação Enhancement / Additive / Critical do web.dev é o framework mais sólido para decidir se uma funcionalidade ausente justifica um polyfill.
A linha de base de suporte nativo em 2026: o que você não precisa mais polyfillizar
A maioria das funcionalidades JavaScript que as configurações de build ainda polyfillizam rotineiramente agora é suportada em todos os browsers evergreen — o que significa que polyfillá-las envia bytes que quase nenhum usuário real precisa. As funcionalidades que ancoraram tutoriais de polyfill por uma década — Math.trunc, Array.prototype.flat, optional chaining — agora são amplamente suportadas e são exatamente o peso morto que uma auditoria de 2026 deve remover.
O exemplo didático por excelência, o polyfill de Math.trunc do javascript.info, é a ilustração mais clara. Math.trunc tem suporte universal nos browsers desde 2015 — segundo os dados de compatibilidade do MDN, foi lançado no Chrome 38, Firefox 25 e Safari 8. Escrever ou empacotar um polyfill de Math.trunc em 2026 é enviar uma cláusula de guarda para um browser que ninguém usa.
O mesmo vale para toda a superfície de API que configurações desatualizadas ainda têm como alvo. Os percentuais de suporte abaixo são extraídos dos dados de uso global do caniuse.com (StatCounter, maio de 2026); “suporte global” refere-se à participação de mercado ponderada de browsers rastreados pelo caniuse em todas as versões.
| Funcionalidade | Suporte global (caniuse, 2026) | Ainda vale polyfillizar? |
|---|---|---|
Array.prototype.flat | 94,11% | Não |
Object.entries | 95,06% | Não |
Promise.allSettled | 94,04% | Não |
structuredClone | 93,84% | Não |
Optional chaining (?.) | 93,99% | Não (sintaxe — transpile, não polyfillize) |
Nullish coalescing (??) | 93,99% | Não (sintaxe — transpile, não polyfillize) |
fetch | 96,3% | Não |
Temporal | 65,16% | Sim — transitório |
| Decorators | 0% nativo | Sim |
Array.flat, Object.entries, Promise.allSettled, structuredClone, optional chaining, nullish coalescing e fetch ficam todos em torno de 94–96% de suporte global — e se sua configuração do Babel ainda está polyfillizando esses recursos, você está enviando bytes que não servem a quase nenhum usuário.
Sintaxe vs. funções: Optional chaining e nullish coalescing são sintaxe, não funções ausentes, portanto são tratados por um transpilador, não por um polyfill. Como o javascript.info coloca: use um transpilador para sintaxe ou operadores modernos, e polyfills para funções ausentes. A distinção importa durante a auditoria — um “polyfill” de
??na sua configuração é um sinal de que a configuração está confundindo os dois conceitos.
Quais polyfills ainda justificam seu lugar em 2026?
Discover how at OpenReplay.com.
Polyfills continuam sendo a ferramenta correta para um conjunto pequeno e específico de casos: funcionalidades sem suporte nativo em lugar algum, funcionalidades em transição entre browsers, e ambientes com browsers bloqueados onde a premissa evergreen não se aplica. Essas são as exceções que justificam manter um mecanismo de polyfill no seu pipeline.
Decorators. A proposta de decorators do TC39 está no Stage 3 sem nenhuma implementação nativa nos browsers. Se você usa decorators — diretamente, ou através de um framework como Angular ou uma biblioteca que depende deles — você está confiando em um transpilador mais, em alguns casos, helpers de runtime. Não existe opção de “aguardar o suporte nativo” aqui ainda; a funcionalidade não está sendo lançada nos browsers.
Temporal, durante sua transição entre browsers. Temporal é uma proposta finalizada do TC39 — aparece na lista de propostas finalizadas do TC39 — e começou a ser lançada nativamente. Segundo os dados de compatibilidade do Temporal no MDN, está disponível no Firefox 139+, Chrome 144+, Edge 144+ e Node.js 26+, enquanto o Safari ainda não tem suporte habilitado. Esse lançamento desigual torna um polyfill do Temporal uma necessidade transitória, não permanente. O repositório proposal-temporal do TC39 lista @js-temporal/polyfill como uma opção em versão alpha junto com alternativas — não é a única escolha canônica.
Ambientes corporativos e de browsers bloqueados. Sistemas financeiros regulamentados, intranets governamentais e dispositivos de quiosque ou PDV às vezes fixam uma versão de browser por anos. Se sua base real de usuários inclui browsers que não podem ser atualizados, seu target no Browserslist é mais amplo do que o padrão evergreen e alguns polyfills são essenciais. A palavra-chave é real — esse caso é alegado com muito mais frequência do que é medido. Valide com base em dados de analytics antes de manter polyfills por essa razão.
Funcionalidades CSS de disponibilidade limitada com polyfills em JavaScript. Algumas capacidades CSS, como container queries em versões mais antigas do Safari, foram polyfillizadas com JavaScript durante seu lançamento. Como o web.dev observa, o polyfill de container queries usa ResizeObserver e MutationObserver para imitar o comportamento nativo — e seu README o marca como não mais mantido. Esses polyfills carregam ressalvas comportamentais abordadas abaixo.
O consenso geral da comunidade — “use polyfills direcionados, baseie decisões em dados” — não está errado, mas subestima o quanto mudou: para a maioria das aplicações em 2026, “polyfills continuam a desempenhar um papel importante” não é mais verdade. O papel agora é estreito e específico.
O incidente do polyfill.io matou o padrão de polyfill remoto
O padrão de polyfill remoto — carregar um <script> de um CDN de terceiros que retorna polyfills adaptados ao browser — não é mais uma arquitetura defensável após o ataque à cadeia de fornecimento do polyfill.io em 2024. O incidente forçou as equipes a auditar o que estavam carregando de terceiros, e a maioria descobriu que não precisava da maior parte.
A linha do tempo:
- Início de 2024 — mudança de propriedade. O domínio polyfill.io mudou de mãos. O post da comunidade da Fastly documenta a mudança e a resposta da Fastly para os usuários afetados.
- 25 de junho de 2024 — relatório de malware. A empresa de segurança Sansec relatou que o serviço polyfill.io estava injetando malware no script que servia aos usuários finais.
- Junho de 2024 — respostas de espelho e mitigação. A Cloudflare anunciou a substituição automática de links do polyfill.io pelo seu próprio espelho, e a Fastly ofereceu um endpoint substituto.
Os espelhos mantêm os sites existentes funcionando, mas não reabilitam o padrão. Um modo de falha padrão em produção que isso expôs: equipes tinham uma tag de script cdn.polyfill.io carregando pacotes de polyfills que haviam deixado de precisar anos antes, executando JavaScript de terceiros em cada carregamento de página para suportar browsers que já tinham sido atualizados. Não trate o espelho da Cloudflare ou da Fastly como um substituto “seguro” — trate o incidente como o gatilho para remover a tag de script completamente e mover quaisquer polyfills genuinamente necessários para o seu próprio bundle, onde você os controla e revisa.
Como auditar o que seu bundler está realmente enviando
Auditar o footprint de polyfills é uma sequência de quatro etapas: ler seu target real no Browserslist, inspecionar o bundle para verificar o peso do core-js, corrigir a configuração do Babel e validar contra dados reais de usuários. Nada disso requer adivinhação — cada etapa é um comando ou um diff de configuração que você pode executar hoje.
Etapa 1: Veja sua lista de targets real
As queries do Browserslist decidem quais browsers sua configuração suporta, e a única forma confiável de saber para o que a sua resolve é perguntar diretamente:
npx browserslist
Isso imprime a lista concreta de versões de browsers que sua configuração atual tem como alvo. Os padrões do Browserslist (> 0.5%, last 2 versions, Firefox ESR, not dead) já excluem o IE11 via not dead. O risco real é uma query personalizada herdada — um > 0.2% perdido ou um limite de versão explícito de anos atrás — que silenciosamente inclui targets antigos. Execute o comando; se a saída incluir browsers que nenhum usuário real usa, esse é o seu peso morto.
Etapa 2: Encontre o peso do core-js no seu bundle
core-js é a biblioteca de polyfills que o @babel/preset-env injeta, e pode representar uma fração substancial de um bundle que não precisa dela. Inspecione um build de produção:
npx source-map-explorer dist/assets/*.js
O source-map-explorer renderiza um treemap do conteúdo de cada bundle a partir de seus source maps. Procure por módulos do core-js — es.array.flat, es.object.entries, es.promise.all-settled. Cada um deles corresponde a uma funcionalidade na tabela de peso morto acima. (Para projetos webpack, o webpack-bundle-analyzer oferece a mesma visão.)
Etapa 3: Corrija a configuração do Babel
A configuração canônica que a maioria das equipes herdou está incompleta. Um padrão comum é assim:
{
"presets": [
["@babel/preset-env", {
"useBuiltIns": "usage",
"corejs": 3
}]
]
}
A configuração acima tem dois problemas. Primeiro, não há campo targets, então a configuração recorre ao seu arquivo Browserslist — que pode ser a query personalizada desatualizada da Etapa 1. Segundo, corejs: 3 não está fixado em uma versão específica; segundo a documentação do core-js, a versão deve especificar um minor para que o preset-env injete polyfills correspondentes à versão instalada. Uma versão adequada para 2026:
{
"presets": [
["@babel/preset-env", {
"targets": "> 1%, last 2 versions, not dead",
"useBuiltIns": "usage",
"corejs": "3.40"
}]
]
}
Fixe corejs na versão minor que você realmente tem instalada em vez de copiar qualquer número — o preset-env usa isso para decidir quais polyfills existem para injetar.
O valor de useBuiltIns é a configuração mais consequente. Segundo a documentação do @babel/preset-env:
'entry'substitui um únicoimport 'core-js'pelo conjunto completo de polyfills que seustargetsrequerem — abrangente, e a fonte da maior parte do bloat herdado.'usage'adiciona polyfills apenas para as funcionalidades que seu código realmente referencia, por arquivo. Isso é quase sempre o que você quer: ele escopa a injeção de polyfills para uso real em vez de toda a sua matriz de targets.
Etapa 4: Valide contra dados reais de usuários
Uma configuração é uma hipótese sobre seus usuários; dados de RUM confirmam ou refutam isso. O web.dev recomenda medir o suporte real de funcionalidades antes de decidir polyfillizar, e aponta o RUM Insights como uma fonte de dados ampla. O padrão ali: funcionalidades no conjunto Baseline Widely available são suportadas por 98% ou mais dos usuários. Se seus dados de analytics mostram uma funcionalidade próxima desse limiar, o polyfill para ela está servindo a uma fatia que arredonda para ruído.
Quando você deve polyfillizar? O framework Enhancement, Additive, Critical
Quando uma funcionalidade genuinamente não é suportada em toda a sua base real de usuários, a classificação Enhancement / Additive / Critical do web.dev é a heurística mais útil para decidir se deve polyfillizar: se uma funcionalidade ausente é invisível para os usuários, não polyfillize; se ela degrada graciosamente, tenda a não polyfillizar; somente se a ausência quebra a experiência um polyfill justifica seu custo de performance.
Os três níveis, como o web.dev os define:
- Enhancement — a funcionalidade melhora a experiência, mas sua ausência não produz nenhuma mudança visual ou perda de funcionalidade. Dicas de performance como
fetchprioritysão o exemplo. Usuários em browsers sem suporte não perceberão. Não polyfillize. - Additive — a funcionalidade pode afetar como uma página parece ou funciona, mas não de uma forma que cause problemas sérios; um usuário pode notar apenas comparando browsers. Se existir um polyfill, tenda a não usá-lo, especialmente se você já está polyfillizando outras coisas. Funções de cor e subgrid são exemplos.
- Critical — a ausência causa uma experiência quebrada: erros de runtime, layouts quebrados, funcionalidade inutilizável. Aqui um polyfill (ou uma abordagem completamente diferente) é justificado.
A regra de ancoragem do web.dev combina bem com a tabela de suporte acima: se uma funcionalidade está Widely available você não deve recorrer a um polyfill — a menos que tenha dados sobre seus usuários que digam explicitamente o contrário.
Por que bugs de polyfill se escondem — e como o session replay os revela
Bugs de polyfill pertencem a uma classe que suítes de teste padrão ignoram completamente: eles só se manifestam na fatia de browsers que ativou o polyfill, que nunca é o browser evergreen contra o qual seu CI executa. Session replay é uma das poucas técnicas de observabilidade que captura o estado real do DOM desses usuários, porque registra a interação real e a sequência de mutações do browser que executou o caminho do polyfill.
Session replay revela três padrões concretos de divergência entre caminhos de código polyfillizados e nativos:
- Timing de layout shift no polyfill de container queries. Como o web.dev observa, o polyfill de container queries direciona o layout a partir de callbacks do
ResizeObserver, que disparam imediatamente antes do browser pintar um novo frame — aumentando o atraso de apresentação e afetando o Interaction to Next Paint. O timing atrasado de repaint pode produzir layout shifts que só são observáveis nos browsers que precisavam do polyfill. - Divergência de fuso horário no Temporal. Durante a transição do Temporal entre browsers, as equipes podem precisar testar tanto as implementações nativas quanto as polyfillizadas do
Temporalpara garantir comportamento consistente entre browsers. Sua suíte de testes pode executar contra apenas um caminho de implementação, enquanto usuários reais encontram outro; replays de browsers onde implementações nativas e polyfillizadas coexistem podem ajudar a revelar essas diferenças. - Lacunas no gerenciamento de foco. Polyfills focados em acessibilidade podem introduzir problemas sutis de navegação por teclado e gerenciamento de foco em browsers sem suporte nativo — o tipo de modo de falha que o web.dev destaca de forma mais geral. Um replay com captura de eventos de teclado mostra o usuário navegando por tab em um backdrop de modal, o que um teste automatizado aprovado contra o polyfill não revelará.
Em cada caso, o fator comum é o mesmo: o bug vive na fatia de usuários que seu ambiente de desenvolvimento nunca reproduz. Essa é a razão estrutural para enviar menos polyfills — cada caminho de polyfill que você remove é um caminho de divergência que você não precisa mais monitorar.
Ações concretas para tomar esta semana
Reduzir seu footprint de polyfills é uma sequência de edições pequenas e reversíveis, cada uma validada contra o bundle e seus usuários. O objetivo é usar o nativo onde puder, carregar condicionalmente para a cauda longa genuína e descartar todo o resto.
- Execute
npx browsersliste delete qualquer query personalizada herdada que tem como alvo browsers que nenhum usuário real usa. Recorrer a um target mais restrito e atual é a mudança de maior impacto. - Defina
useBuiltIns: 'usage'e um campotargetsexplícito na sua configuração do@babel/preset-env, e fixecorejsna sua versão minor instalada. - Compare o bundle antes e depois com
source-map-explorerpara confirmar que o peso docore-jsrealmente diminuiu, depois execute seus testes para verificar que nada que você precisava desapareceu. - Remova qualquer tag de script
cdn.polyfill.iocompletamente; mova quaisquer polyfills genuinamente necessários para o seu próprio bundle. - Carregue condicionalmente as exceções genuínas. Para o Temporal durante sua transição, carregue o polyfill apenas para os browsers que precisam dele em vez de enviá-lo para todos. Para Decorators, confie na transpilação e em helpers de runtime onde necessário. O ponto do web.dev de que polyfills para funcionalidades de disponibilidade limitada devem ser carregados condicionalmente se aplica diretamente.
- Valide com dados de RUM antes e depois, para que a auditoria se baseie nos seus usuários, não na média global.
Conclusão
A resposta honesta de 2026 para se alguém ainda usa polyfills é sim — mas a lista defensável é curta e específica: Decorators, Temporal enquanto cruza a lacuna entre browsers, e ambientes de browsers bloqueados que você realmente mediu. Todo o resto que sua configuração herdou são bytes gastos em uma fatia de mercado de browsers que arredonda para zero, e o incidente do polyfill.io é o lembrete de que carregá-los descuidadamente carrega risco real. Comece com npx browserslist hoje; a lacuna entre o que ele imprime e os browsers que seus usuários realmente usam é o seu orçamento de polyfills, e para a maioria das equipes é muito menor do que a configuração assume.
Perguntas Frequentes
Qual é a diferença entre um polyfill e um transpilador?
Um transpilador reescreve sintaxe moderna em um equivalente mais antigo em tempo de build, enquanto um polyfill adiciona uma função ou implementação de API ausente em tempo de execução. Funcionalidades de sintaxe como optional chaining e nullish coalescing são tratadas por um transpilador porque são operadores de linguagem, não funções chamáveis. APIs como Promise.allSettled ou structuredClone são tratadas por polyfills porque são métodos ausentes que o código de runtime pode fornecer. Um 'polyfill' de nullish coalescing na sua configuração sinaliza que os dois conceitos foram confundidos.
Qual é a diferença entre useBuiltIns 'usage' e 'entry' no babel-preset-env?
Com useBuiltIns definido como 'entry', o Babel substitui um único import do core-js pelo conjunto completo de polyfills que seus targets requerem, o que é a fonte da maior parte do bloat herdado no bundle. Com 'usage', o Babel injeta polyfills apenas para as funcionalidades que seu código realmente referencia, com escopo por arquivo. O valor 'usage' é quase sempre preferível porque envia polyfills para uso real em vez de toda a sua matriz de targets. Ambos requerem uma versão do corejs fixada na sua versão minor instalada.
É seguro continuar usando o polyfill.io através do espelho da Cloudflare ou da Fastly?
Os espelhos da Cloudflare e da Fastly mantêm os sites existentes funcionando, mas não reabilitam o padrão de polyfill remoto. Após o domínio polyfill.io mudar de propriedade no início de 2024 e a Sansec relatar em 25 de junho de 2024 que o serviço estava injetando malware, carregar polyfills adaptados ao browser de um CDN de terceiros tornou-se indefensável para equipes com consciência de segurança. Remova a tag de script cdn.polyfill.io completamente e mova quaisquer polyfills genuinamente necessários para o seu próprio bundle, onde você os controla e revisa.
Ainda preciso do core-js se minha aplicação tem como alvo apenas browsers evergreen?
Para a maioria das aplicações com alvo evergreen em 2026, o core-js envia próximo de zero polyfills úteis, porque funcionalidades como Array.flat, Object.entries, Promise.allSettled, structuredClone e fetch já são amplamente suportadas. As exceções nomeadas são Decorators, que não tem implementação nativa nos browsers, e Temporal durante seu lançamento desigual entre browsers. Execute o source-map-explorer contra um build de produção para ver quais módulos do core-js estão presentes, depois ajuste seu target no Browserslist e mude useBuiltIns para 'usage' para eliminar o peso morto.