2026 E o Ano da Adocao Completa de ES Modules no JavaScript
Ola HaWkers, apos anos de transicao, 2026 marca o ano em que ES Modules (ESM) finalmente atinge adocao completa no ecossistema JavaScript. O Node.js agora permite importar ESM de CommonJS, bibliotecas principais estao dropando suporte a CJS, e a comunidade esta convergindo para um unico sistema de modulos.
Se voce ainda esta usando CommonJS em seus projetos, este e o momento de migrar. Vamos entender por que essa mudanca e tao importante e como fazer a transicao de forma segura.
O Que Mudou em 2026
A Virada Definitiva
Varios fatores convergiram para tornar 2026 o ano do ESM.
Marcos importantes:
- Node.js 24 LTS: Suporte completo a ESM como padrao
- Node.js 22+: Permite
import()de ESM dentro de arquivos CJS - npm trends: 70%+ das novas bibliotecas sao ESM-only
- Principais bibliotecas: chalk, execa, got, ora droparam CJS
Comparacao de ecosistema:
| Ano | Bibliotecas ESM-only | Bibliotecas Dual | CJS-only |
|---|---|---|---|
| 2020 | 5% | 15% | 80% |
| 2022 | 15% | 30% | 55% |
| 2024 | 35% | 40% | 25% |
| 2026 | 60% | 30% | 10% |
Citacao de um core maintainer do Node.js:
"Finalmente podemos dizer que ES Modules e o caminho padrao para JavaScript. A interoperabilidade com CommonJS esta madura o suficiente para que a transicao seja suave."
Por Que ES Modules e Melhor
Vantagens Tecnicas
ES Modules oferece beneficios concretos sobre CommonJS.
1. Import estatico e tree-shaking:
// CommonJS - importa tudo
const _ = require('lodash');
const result = _.map([1, 2, 3], x => x * 2);
// ESM - importa apenas o necessario
import { map } from 'lodash-es';
const result = map([1, 2, 3], x => x * 2);
// Resultado: bundle 70% menor com ESM + tree-shaking2. Top-level await:
// ESM permite await no nivel superior
const config = await fetch('/config.json').then(r => r.json());
const db = await connectDatabase(config.dbUrl);
export { db, config };
// CommonJS exigiria wrapper async ou callbacks3. Resolucao de modulos mais previsivel:
// ESM - sempre precisa da extensao
import { helper } from './utils.js';
import data from './data.json' assert { type: 'json' };
// URLs e imports dinamicos
const module = await import(`./plugins/${pluginName}.js`);4. Compatibilidade com navegadores:
<!-- ESM funciona nativamente no browser -->
<script type="module">
import { render } from './app.js';
render(document.getElementById('root'));
</script>
Como Migrar de CommonJS Para ESM
Guia Passo a Passo
Migrar um projeto existente requer alguns passos especificos.
Passo 1: Atualizar package.json
{
"name": "meu-projeto",
"version": "1.0.0",
"type": "module",
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.cjs"
}
},
"engines": {
"node": ">=18.0.0"
}
}Passo 2: Renomear arquivos (se necessario)
# Se nao usar "type": "module", renomeie para .mjs
mv src/index.js src/index.mjs
# Ou mantenha .js com "type": "module" no package.jsonPasso 3: Atualizar imports/exports
// Antes (CommonJS)
const express = require('express');
const { readFile } = require('fs').promises;
const myModule = require('./myModule');
module.exports = { app, server };
module.exports.helper = helper;
// Depois (ESM)
import express from 'express';
import { readFile } from 'fs/promises';
import myModule from './myModule.js'; // Note a extensao
export { app, server };
export { helper };Passo 4: Lidar com __dirname e __filename
// CommonJS tinha __dirname e __filename globais
// ESM precisa recria-los
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Uso
const configPath = join(__dirname, 'config.json');
Casos Especiais na Migracao
Lidando Com Dependencias CommonJS
Nem todas as bibliotecas migraram para ESM.
Importando CJS em ESM:
// Importacao padrao funciona para a maioria dos casos
import lodash from 'lodash'; // CJS
// Para named exports de CJS, pode precisar de:
import pkg from 'some-cjs-package';
const { namedExport } = pkg;
// Ou use createRequire para casos especiais
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const legacyLib = require('legacy-cjs-lib');Importando ESM em CJS (Node.js 22+):
// Agora e possivel em Node.js 22+
// arquivo.cjs ou arquivo sem "type": "module"
async function main() {
// Import dinamico funciona
const { something } = await import('esm-only-package');
// Ou no topo do arquivo com a nova feature
}
// Node.js 22+ tambem suporta require() de ESM sicrono
// em alguns casosDual package (suportar ambos):
{
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
},
"./utils": {
"import": "./dist/utils.mjs",
"require": "./dist/utils.cjs"
}
}
}
Ferramentas Para a Migracao
Automatizando o Processo
Varias ferramentas ajudam na migracao.
1. cjs-to-esm
# Converte arquivos CJS para ESM
npx cjs-to-esm src/**/*.js
# Opcoes
npx cjs-to-esm --ext=.mjs src/**/*.js2. ESLint para validacao
// .eslintrc.js
export default {
parserOptions: {
sourceType: 'module',
ecmaVersion: 2026,
},
rules: {
// Garante uso correto de ESM
'import/extensions': ['error', 'always'],
'import/no-commonjs': 'error',
},
};3. TypeScript com ESM
// tsconfig.json
{
"compilerOptions": {
"module": "NodeNext",
"moduleResolution": "NodeNext",
"target": "ES2022",
"outDir": "./dist",
"declaration": true
}
}4. Vite e bundlers modernos
// vite.config.js - ESM por padrao
import { defineConfig } from 'vite';
export default defineConfig({
build: {
lib: {
entry: './src/index.js',
formats: ['es', 'cjs'],
fileName: (format) => `index.${format === 'es' ? 'mjs' : 'cjs'}`
}
}
});
Problemas Comuns e Solucoes
Troubleshooting
Alguns problemas frequentes na migracao.
Erro: "require is not defined"
// Problema: usando require() em arquivo ESM
// Solucao: usar import ou createRequire
// Errado
const fs = require('fs'); // Erro em ESM
// Certo
import fs from 'fs';
// ou
import { createRequire } from 'module';
const require = createRequire(import.meta.url);Erro: "Cannot use import statement outside a module"
// Problema: arquivo nao esta sendo tratado como ESM
// Solucoes:
// 1. Adicione "type": "module" no package.json
// 2. Renomeie o arquivo para .mjs
// 3. Use a flag --experimental-vm-modules (testes)Erro: "ERR_MODULE_NOT_FOUND"
// Problema: falta extensao no import
// ESM requer extensoes explicitas
// Errado
import { helper } from './utils';
// Certo
import { helper } from './utils.js';Problema com JSON imports:
// ESM requer assertion para JSON
import data from './data.json' assert { type: 'json' };
// Ou use createRequire
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const data = require('./data.json');
O Impacto no Ecossistema
Mudancas em Bibliotecas Populares
Muitas bibliotecas ja migraram ou estao migrando.
Bibliotecas que droparam CommonJS:
| Biblioteca | Versao ESM-only | Alternativa CJS |
|---|---|---|
| chalk | 5.0+ | chalk@4 |
| execa | 6.0+ | execa@5 |
| got | 12.0+ | got@11 |
| ora | 6.0+ | ora@5 |
| globby | 13.0+ | globby@12 |
| node-fetch | 3.0+ | node-fetch@2 |
Estrategias das bibliotecas:
- ESM-only: Forca usuarios a migrar (chalk, got)
- Dual package: Suporta ambos (axios, lodash)
- CJS com wrapper ESM: Mantem CJS, exporta ESM (express)
Recomendacao:
Para novos projetos, use ESM desde o inicio. Para projetos existentes, planeje a migracao gradualmente, comecando pelos modulos menos criticos.
Beneficios de Performance
Por Que ESM e Mais Rapido
A mudanca para ESM traz ganhos de performance.
Tree-shaking efetivo:
// Bundle size comparison (exemplo real)
// Projeto usando lodash
// CommonJS: 72KB (lodash inteiro)
// ESM com tree-shaking: 4KB (so funcoes usadas)Carregamento paralelo no browser:
// ESM permite carregamento paralelo de dependencias
// O browser resolve o grafo de imports e carrega em paralelo
// Resultado: tempo de carregamento 30-50% menor
// para aplicacoes com muitos modulosCache mais eficiente:
// Cada modulo ESM pode ser cacheado independentemente
// Mudancas em um modulo nao invalidam outros
// Beneficio em CI/CD e builds incrementaisConclusao
2026 marca a consolidacao de ES Modules como o padrao do JavaScript. A transicao pode parecer trabalhosa, mas os beneficios em termos de performance, compatibilidade e developer experience justificam o esforco.
Pontos principais:
- ES Modules e agora o padrao de facto do JavaScript
- Node.js 22+ permite interoperabilidade completa
- Migrar requer atencao a extensoes e sintaxe
- Ferramentas automatizam grande parte do processo
- Beneficios incluem tree-shaking e melhor performance
Recomendacoes:
- Comece novos projetos com ESM
- Planeje migracao de projetos existentes
- Use ferramentas de conversao automatica
- Teste extensivamente apos migracao
- Mantenha dual package se necessario para compatibilidade
Para mais sobre JavaScript moderno, leia: ES2026: Novos Recursos que Vao Transformar Como Escrevemos JavaScript.

