What Is New in Node.js 13?
| Category | Change |
|---|---|
| New Features | Full ES Modules support enabled by default (experimental) |
| New Features | Top-level await in ES module scripts |
| New Features | V8 7.9 -- Promise.allSettled, String.matchAll |
| Improvements | require() caching improvements across symlinks |
| Improvements | --experimental-specifier-resolution flag for Node.js module resolution in ESM |
| Improvements | ICU data updated to Unicode 12.1 |
| Security | TLS 1.3 now the default |
ES Modules -- Moving From Experimental to Mainstream
Node.js 13 significantly advances ESM support. Files with .mjs extension or "type": "module" in package.json are loaded as ES Modules by default. import/export syntax works without any flags.
// math.mjs
export const add = (a, b) => a + b;
// app.mjs
import { add } from './math.mjs';
console.log(add(1, 2));
This is a pivotal release for any team considering moving away from CommonJS. The ESM implementation is incomplete compared to later versions (no named exports from JSON, no import maps) but usable for pure JS projects.
Promise.allSettled() and String.matchAll()
Promise.allSettled() waits for all promises in an iterable to resolve or reject, and returns an array of outcome objects. Unlike Promise.all(), it never short-circuits on a rejection -- every promise runs to completion.
const results = await Promise.allSettled([fetchA(), fetchB(), fetchC()]);
for (const r of results) {
if (r.status === 'fulfilled') process(r.value);
else logError(r.reason);
}
String.matchAll() returns an iterator of all regex match objects with capture groups, replacing the awkward while+exec loop pattern.
TLS 1.3 as Default
Node.js 13 sets TLS 1.3 as the default protocol for new TLS connections. TLS 1.3 reduces handshake round-trips and removes several weak cipher suites mandatorily. Most modern servers support it, but older proxies or appliances may still require TLS 1.2 as a fallback.
FAQ
Can I mix CommonJS and ES Modules in Node.js 13?
Partially. ESM files can import CJS modules, but CJS files cannot use import to load ESM. Use dynamic import() in CJS to load ESM modules asynchronously.
Is Node.js 13 an LTS release?
No. Node.js 13 is a Current release that reached end-of-life in June 2021. The concurrent LTS was Node.js 12.
What does --experimental-specifier-resolution=node do?
It enables Node.js-style module resolution in ESM -- allowing imports without file extensions (import './utils' instead of import './utils.js'). Without it, ESM requires explicit extensions.
Does top-level await work in .js files in Node.js 13?
Only in files treated as ES Modules (.mjs or "type": "module"). Regular .js files are still CommonJS and do not support top-level await.
Can I still use require() in Node.js 13 ESM files?
No. require() is not available in native ESM. Use createRequire() from node:module if you need to import a CJS module from an ESM context.