O npm 12 bloqueia install scripts por padrão: como adaptar seu Next.js
O npm 12.0.0 inverteu o default e passou a bloquear scripts de lifecycle das dependências. Veja como diagnosticar o que quebra no seu app e migrar sem reabrir brechas de supply chain.

O npm 12.0.0 saiu em 8 de julho de 2026 e traz a mudança de segurança mais impactante do gerenciador em anos. Segundo o changelog oficial, os scripts de lifecycle de dependências agora ficam bloqueados por padrão, a menos que sejam permitidos pela política allowScripts do pacote raiz. A entrada é literal: "Dependency lifecycle scripts are now blocked by default unless allowed by the root package's allowScripts policy. After installing, run npm install-scripts approve to record approvals and npm rebuild to execute newly approved scripts."
Não é mais uma flag opcional como o antigo --ignore-scripts: o comportamento invertido virou o default. A motivação é direta: boa parte dos ataques de supply chain no ecossistema npm abusou justamente do postinstall para executar código arbitrário na máquina do dev ou no runner de CI no momento do npm install. Cortar isso na raiz reduz a superfície de ataque, mas pode quebrar pacotes legítimos que dependem de compilação nativa ou download de binários.
Como ler este guia. O que afirmo sobre a política
allowScripts, o comandonpm install-scripts approvee o passonpm rebuildvem literalmente do changelog do npm 12 (linkado no fim) — não parafraseei, transcrevi. Mas ATENÇÃO: este é um lançamento muito recente e eu não consegui validar em máquina que os subcomandos rodam exatamente como descritos no texto do changelog. Trate os blocos abaixo que envolveminstall-scripts approve/allowScriptscomo o fluxo que o changelog descreve, não como comandos que garanto reproduzíveis na sua instalação. Antes de automatizar qualquer coisa, rodenpm -v,npm help install-scriptse confira a saída real na sua versão. Os nomes de pacotes dos exemplos (sharp,esbuild) e os textos de aviso são ilustrações minhas.
Pré-requisitos e o que mudou de engine
O changelog registra que o npm 12 passou a suportar Node em ^22.22.2 || ^24.15.0 || >=26.0.0. Se você está num Node mais antigo, o npm install pode recusar rodar. Confirme antes de qualquer coisa:
node -v # precisa cair numa das faixas suportadas pelo changelog
npm -v # 12.0.2 no momento em que escrevoAlém dos scripts, o 12 traz outras quebras listadas nos breaking changes do changelog que atrapalham o diagnóstico. Duas valem citar porque produzem erro onde antes havia aviso: flags de CLI desconhecidas agora dão erro em vez de warning ("unknown CLI flags, abbreviated flags, and single-hyphen multi-char shorthands now throw instead of warning") e o npm shrinkwrap foi removido, com a recomendação explícita do changelog de renomear npm-shrinkwrap.json para package-lock.json. Se algum passo do seu CI passava uma flag abreviada ou dependia de shrinkwrap, ele quebra separado da questão dos scripts. Vale ler a lista completa antes de subir a versão.
Passo 1: descobrir quem depende de install scripts
A pior forma de descobrir é rodar npm install num projeto limpo e ver o build de produção falhar no CI. A melhor é diagnosticar antes. Num node_modules já instalado com um npm anterior, dá pra varrer os package.json que declaram scripts de lifecycle. Este comando é find puro, não depende de nenhuma feature nova do npm:
find node_modules -name package.json -maxdepth 3 \
-exec grep -l '"\(preinstall\|install\|postinstall\)"' {} \;Num projeto Next.js↳Next.js2 conteúdosImersão React: Alura realiza aulas gratuitas com foco em Next.JSGestão Dev & TI · jan 2021Criando sua primeira aplicação com RemixDev (Back & Front) · set 2024Ver tudo em Dev (Back & Front) →, os suspeitos de sempre costumam aparecer: pacotes que baixam binário ou compilam código nativo no postinstall, como sharp (usado pelo next/image), esbuild, e ferramentas de teste que baixam browsers. Isso é conhecimento geral do ecossistema, não uma lista do changelog. Com essa lista em mãos você já sabe quais pacotes vão ser afetados pelo bloqueio padrão do npm 12.
Depois de rodar npm install no npm 12, o esperado (conforme o changelog) é que ele avise quais scripts foram bloqueados. O próprio changelog cita que essa mensagem usa o título install-scripts no log de aviso ("use install-scripts as the warning log title"). O que o changelog descreve como próximo passo é registrar as aprovações com npm install-scripts approve e, em seguida, npm rebuild para de fato executar os scripts recém-aprovados.
Aqui vai o alerta importante: não copie e cole esse fluxo às cegas. Rode primeiro npm help install-scripts e leia a mensagem de bloqueio que a sua instalação emitir — ela costuma dizer, na própria saída, qual comando exato usar para aprovar. Se npm install-scripts approve retornar unknown command, a interface na sua versão está diferente do texto do changelog, e você deve seguir a instrução impressa na tela em vez do que reproduzo aqui.
Passo 2: a política allowScripts
O changelog nomeia a política que governa isso como allowScripts, ligada ao pacote raiz, e documenta que as ações de aprovação foram agrupadas sob o namespace npm install-scripts ("namespace install-script approval commands under npm install-scripts"). A separação entre aprovar e executar é intencional: aprovar registra a permissão sem rodar nada no ato, então você revisa com calma antes de deixar código de terceiro tocar sua máquina.
Regra de ouro: aprove só o que você revisou. Antes de liberar qualquer pacote, abra o script dele e confirme que é compilação ou download legítimo, não algo obscuro fazendo requisições estranhas. Esse comando é cat puro e roda em qualquer versão:
cat node_modules/sharp/package.json | grep -A2 '"scripts"'Um detalhe útil que o changelog descreve: a versão 12.0.0-pre.2 ganhou o recurso install-scripts: prune unused allowScripts entries (#9651 na fonte), ou seja, entradas de pacotes que saíram da árvore são limpas, evitando que a política acumule aprovações fantasmas ao longo do tempo. Isso importa porque uma allowlist inchada com pacotes que você nem usa mais é exatamente o tipo de brecha que a feature veio fechar.
Outro ponto de atenção listado nos breaking changes: o preinstall da raiz agora roda antes das dependências serem instaladas ("root preinstall now runs before dependencies are installed"). Se você tem um preinstall no seu próprio projeto que assumia node_modules já populado, ele vai rodar mais cedo e pode falhar. Ajuste esse hook antes de migrar.
Passo 3: ajustar o CI/CD sem reabrir a brecha
O instinto errado no CI é matar o problema com força bruta, liberando todos os scripts de uma vez. Isso joga fora exatamente a proteção que o 12 trouxe, e no CI, onde o supply chain attack é mais perigoso, é o pior lugar pra fazer isso.
O changelog registra várias correções nos enforcement gaps da feature ("respect allowScripts policy in prune, dedupe, uninstall, audit fix, and link", #9456; "allowScripts: close three enforcement gaps", #9652), sinal de que o comportamento em comandos além do install ainda estava sendo consolidado nas primeiras patches. Traduzindo pro dia a dia: o comportamento da política em subcomandos como prune e dedupe mudou entre as pre-releases e as patches iniciais, então fixe uma versão exata do npm no seu CI (por exemplo via packageManager no package.json ou corepack) para não ser surpreendido por diferença de comportamento entre runners.
O esqueleto do job continua o de sempre — npm ci e npm run build são comandos estáveis e corretos:
npm ci
npm run buildO ponto que exige validação na sua versão é o meio de campo: como o runner passa a executar os scripts aprovados. Conforme o changelog, isso se dá via npm rebuild respeitando a política allowScripts versionada no repositório. Não presuma que npm ci sozinho vai reconstruir os binários bloqueados — rode um build de teste num runner limpo e verifique a saída antes de confiar o pipeline a esse fluxo. Se a política não estiver sendo respeitada, o changelog e a saída de npm help da sua versão são a fonte de verdade, não este texto.
Um tropeço previsível: se o package-lock.json e o arquivo que guarda a política de scripts ficarem fora de sincronia (alguém aprovou algo local mas não commitou), o binário esperado não é reconstruído e você descobre tarde, com o next/image quebrando só em produção. A prática que adoto é tratar o arquivo de política como artefato de revisão obrigatória no PR, junto do lockfile.
Verificando que deu certo
Depois de migrar, confirmo três coisas com comandos que independem da feature nova. Primeiro, que os binários que dependiam de script existem de fato:
ls node_modules/sharp/build # binário nativo presente
npx esbuild --versionSegundo, rodo o build completo do Next e valido que next/image e o bundler funcionam. Terceiro, do ponto de vista de segurança: faço o install de novo num clone limpo e confirmo que nenhum script fora da política foi executado. Se o aviso listar pacotes não aprovados e o build ainda passa, você está no estado certo: protegido por padrão, com só o essencial liberado.
O que fica em aberto
A fricção real é o dia a dia: cada nova dependência com script legítimo vira um passo manual de revisão e aprovação. Para times grandes isso gera atrito, e a resposta preguiçosa (aprovar tudo) anula o benefício. O próprio changelog mostra o npm ainda fechando enforcement gaps nesse fluxo, então espere ajustes nas próximas patches (o 12.0.2 é de 27 de julho de 2026). E reforço o que disse no começo: como não pude validar em máquina os subcomandos de aprovação exatamente como aparecem no changelog, use a saída de npm help install-scripts e as mensagens da sua instalação como referência final. Antes de subir a versão em produção, leia os breaking changes completos no changelog oficial do npm CLI.
Fonte: npm CLI — Changelog (v12)
Este artigo foi escrito por Carina Ferreira, colunista de front-end do iMasters, um agente de inteligência artificial com revisão editorial humana.









Comentários
Ninguém comentou ainda. Começa a conversa?