Seit 2015 erscheint jedes Jahr im Juni eine neue ECMAScript-Edition. Hinter dem stabilen Release-Zug steht das Komitee TC39 mit einem klar definierten Stage-Process, der Vorschlaege von der Idee bis in den Standard fuehrt. Dieser Artikel zeichnet den Weg von ES2015 bis ES2025 nach, ordnet die wichtigsten Features ihrer Edition zu und gibt einen Ausblick auf ES2026 sowie auf Stage-3-Features, die kurz vor der Aufnahme stehen.

Yearly Release Train seit ES2015

Bis 2015 lief die Sprachentwicklung in unregelmäßigen, oft mehrjährigen Abständen. ES1 erschien 1997, ES3 1999, ES5 erst 2009 — dazwischen versuchte ES4 einen großen Sprung, der politisch scheiterte. Mit ES2015 (umgangssprachlich „ES6") brach TC39 mit dem Modell und stellte auf einen jährlichen Release-Zug um:

  • Jede Edition wird im Juni ratifiziert.
  • Aufgenommen wird, was bis zur Stage 4 gereift ist; alles andere bleibt für die nächste Edition.
  • Die Edition ist eine Momentaufnahme — das eigentliche Tempo bestimmt der Stage-Process.

Das vermeidet die ES4-Falle: keine Mega-Releases, sondern viele kleine Schritte. Engines können Features einzeln implementieren, Tooling kann sie einzeln transpilieren, Entwickler können sie einzeln lernen.

Der TC39-Stage-Process

Hinter jedem Feature steht ein definierter Reifeprozess. TC39 (Technical Committee 39) verwaltet ihn über fuenf Stufen:

StageNameWas bedeutet das?
0StrawpersonErste Idee, ohne formale Anforderungen.
1ProposalChampion übernimmt, Problem und Skizze einer Lösung sind dokumentiert.
2DraftSpec-Text für Syntax und Semantik liegt vor; Richtung ist beschlossen.
2.7CandidateSpec ist vollständig, Reviewer-Sign-off, Test262-Tests vorbereitet.
3CandidateImplementations-Reife — Engines sollen das Feature jetzt bauen.
4FinishedZwei Test262-konforme Implementierungen vorhanden; Aufnahme in die nächste Edition.

TC39 entscheidet per Konsens — kein Voting. Ein einzelner Editor oder Vendor kann ein Proposal blockieren, was selten passiert, aber Konsens erzwingt. Champions begleiten ihren Vorschlag durch alle Stufen und pflegen das Repository auf github.com/tc39.

ES2015/ES6 — der große Reset

ES2015 ist die wichtigste Edition seit Bestehen der Sprache. Sie fuegt nicht ein paar Methoden hinzu, sondern verschiebt das Schreibmuster:

  • let und const — block-scoped Variablen ersetzen var in fast jedem Anwendungsfall.
  • Arrow Functions — kompakte Syntax, lexikalisches this.
  • Klassen — syntaktischer Zucker auf Prototyp-Vererbung.
  • Template Literals — String-Interpolation und Multiline ohne Konkatenation.
  • Destructuring und Spread/Rest — pragmatische Datentransformationen.
  • Default Parameters — saubere Default-Werte statt ||-Tricks.
  • Symbols — neue primitive Datentyp für einzigartige Schlüssel.
  • Promises — natives Async-Modell statt Callback-Hell.
  • Iterators und Generators — Protokoll für iterable Datenstrukturen, for...of.
  • ES Modulesimport/export als Standard, vorher CommonJS oder AMD.
  • Map, Set, WeakMap, WeakSet — neue Datenstrukturen für Schlüssel-Objekte und schwache Referenzen.
  • Proxy und Reflect — programmierbare Meta-Objekte.
JavaScript es2015-highlights.js
// 1. let/const, Arrow, Klassen, Template Literals, Destructuring
const greet = (name = "Welt") => `Hallo, ${name}!`;

class User {
    constructor({ firstname, lastname }) {
        this.firstname = firstname;
        this.lastname = lastname;
    }
    get fullName() {
        return `${this.firstname} ${this.lastname}`;
    }
}

const u = new User({ firstname: "Ada", lastname: "Lovelace" });
console.log(greet(u.fullName));

// 2. Promises + Module-Style (in einer .mjs-Datei)
const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
wait(100).then(() => console.log("Promise erfüllt"));

ES2016–ES2019 — Stabilisierung

Nach dem großen Wurf folgten kompakte Releases, die das Bild abrundeten:

  • ES2016Array.prototype.includes, Exponentiations-Operator **.
  • ES2017async/await, Object.values, Object.entries, String.prototype.padStart/padEnd, Object.getOwnPropertyDescriptors.
  • ES2018 — Rest/Spread für Objekte ({ ...obj }), Async Iteration (for await...of), Promise.prototype.finally, RegExp-Lookbehind, Named Capture Groups, s-Flag (dotAll).
  • ES2019Array.prototype.flat/flatMap, Object.fromEntries, String.prototype.trimStart/trimEnd, optionales catch-Binding (try { } catch { }), well-formed JSON.stringify.
JavaScript es2017-async-await.js
// ES2015 Promise-Chain
function loadUserChain(id) {
    return fetchJson(`/users/${id}`)
        .then(user => fetchJson(`/orders?u=${user.id}`)
            .then(orders => ({ user, orders })));
}

// ES2017 async/await — gleiche Logik, sequenzieller Stil
async function loadUser(id) {
    const user = await fetchJson(`/users/${id}`);
    const orders = await fetchJson(`/orders?u=${user.id}`);
    return { user, orders };
}
Output
// async/await ist syntaktischer Zucker auf Promises;
// .then ist und bleibt unten drunter

ES2020–ES2022 — Modern Era

Diese Editionen brachten Features, die heute aus modernem Code kaum noch wegzudenken sind:

  • ES2020 — Optional Chaining (?.), Nullish Coalescing (??), BigInt, dynamic import(), Promise.allSettled, globalThis, String.prototype.matchAll.
  • ES2021String.prototype.replaceAll, Promise.any, Logical Assignment (||=, &&=, ??=), Numeric Separators (1_000_000), WeakRef.
  • ES2022 — Top-Level await, Class Fields (public/private), .at(-1), Object.hasOwn, Error.cause, RegExp Match Indices.
JavaScript es2020-optional-nullish.js
const config = {
    db: { host: "localhost" },
    cache: null
};

// Optional Chaining: bricht bei null/undefined ohne TypeError ab
const port = config.db?.port;            // undefined
const ttl  = config.cache?.ttl;          // undefined
const fn   = config.logger?.debug?.();   // undefined

// Nullish Coalescing: Default nur bei null/undefined,
// nicht bei 0, "" oder false (im Gegensatz zu ||)
const timeout = config.timeout ?? 5000;
const debug   = config.debug   ?? false;

console.log({ port, ttl, fn, timeout, debug });
Output
{ port: undefined, ttl: undefined, fn: undefined, timeout: 5000, debug: false }
JavaScript es2022-class-fields.js
// Top-Level await in ESM
const data = await fetch("/api/config").then(r => r.json());

class Counter {
    // Public Field
    value = 0;
    // Private Field — echte Private, nicht Konvention
    #step = 1;

    inc() {
        this.value += this.#step;
        return this.value;
    }
}

const c = new Counter();
c.inc();
c.inc();

// .at(-1) liest vom Ende
const last = [10, 20, 30].at(-1);

// Error.cause erhaelt die ursprüngliche Fehler-Kette
try {
    try { throw new Error("DB offline"); }
    catch (e) { throw new Error("Setup fehlgeschlagen", { cause: e }); }
} catch (e) {
    console.log(e.message, "->", e.cause.message);
}
console.log(c.value, last);
Output
Setup fehlgeschlagen -> DB offline
2 30

ES2023–ES2024 — Methoden-Konsolidierung

Beide Editionen schließen Lücken, die im Alltag schmerzten:

  • ES2023Array.prototype.findLast/findLastIndex, immutable Array-Pendants (toSorted, toReversed, toSpliced, with), Hashbang-Grammatik (#!/usr/bin/env node), Symbols als WeakMap-Schlüssel.
  • ES2024Object.groupBy/Map.groupBy, Promise.withResolvers, RegExp /v-Flag, Atomics.waitAsync, ArrayBuffer.prototype.transfer, resizable ArrayBuffer.
JavaScript es2023-immutable-array.js
const numbers = [3, 1, 4, 1, 5, 9, 2, 6];

// ES2023 — immutable: Original bleibt unangetastet
const sortedAsc = numbers.toSorted((a, b) => a - b);
const reversed  = numbers.toReversed();
const replaced  = numbers.with(0, 99); // Index 0 -> 99

console.log("Original:", numbers);
console.log("toSorted:", sortedAsc);
console.log("toReversed:", reversed);
console.log("with(0, 99):", replaced);

// Vergleich: das alte sort() mutiert in-place
const copy = [...numbers];
copy.sort((a, b) => a - b);
// copy ist jetzt sortiert; numbers war es schon vorher (Kopie!)
Output
Original: [3,1,4,1,5,9,2,6]
toSorted: [1,1,2,3,4,5,6,9]
toReversed: [6,2,9,5,1,4,1,3]
with(0, 99): [99,1,4,1,5,9,2,6]

ES2025 — die aktuelle Edition

Im Juni 2025 ratifiziert. Die Highlights:

  • Iterator Helpers.map, .filter, .take, .drop, .flatMap, .reduce, .toArray direkt auf Iteratoren. Faul ausgewertet, ideal für Generatoren und unendliche Sequenzen.
  • Set-Methodenintersection, union, difference, symmetricDifference, isSubsetOf, isSupersetOf, isDisjointFrom.
  • Promise.try — startet einen synchronen Block in einem Promise-Kontext und faengt sowohl synchrone Wuerfe als auch zurückgegebene Promises ab.
  • RegExp.escape — schreibt einen String literal-sicher in eine Regex.
  • Float16Array — typed Array für 16-Bit-Floats (ML, GPU-Buffer).
  • Import Attributes und JSON Modulesimport data from "./x.json" with { type: "json" }.
  • RegExp Modifiers — flags inline aktivieren/deaktivieren ((?i:...)).
JavaScript es2025-iterator-helpers.js
function* naturals() {
    let n = 1;
    while (true) yield n++;
}

// Faule Auswertung: nur 5 Werte werden aus dem unendlichen Generator gezogen
const firstFiveSquaresOfEvens = naturals()
    .filter(n => n % 2 === 0)
    .map(n => n * n)
    .take(5)
    .toArray();

console.log(firstFiveSquaresOfEvens);

// ES2025 Set-Methoden
const a = new Set([1, 2, 3, 4]);
const b = new Set([3, 4, 5, 6]);
console.log([...a.intersection(b)]); // [3, 4]
console.log([...a.union(b)]);        // [1, 2, 3, 4, 5, 6]
console.log([...a.difference(b)]);   // [1, 2]
Output
[4, 16, 36, 64, 100]
[3, 4]
[1, 2, 3, 4, 5, 6]
[1, 2]

ES2026 Working Draft / Stage-3-Ausblick

Was zur Mitte 2026 in der Edition landet, ergibt sich aus dem aktuellen Stage-3-Bestand. Bereits als Stage-4-Finished für ES2026 vermerkt sind unter anderem:

  • Array.fromAsyncPromise.all für Async-Iterables.
  • Error.isError — verlässlicher Branding-Check über Realms hinweg.
  • Math.sumPrecise — exakte Summe von Floats ohne Rundungsfehler.
  • Uint8Array to/from Base64 — Standard-API für Binär-Encoding.
  • JSON.parse source text access — Zugriff auf den Roh-String beim Parsen.

Auf Stage 3 und damit kurz vor der Aufnahme stehen weitere Schwergewichte:

  • Decorators — neue Spec, nicht binärkompatibel zu den TS-Legacy-Decorators.
  • Explicit Resource Managementusing und await using mit Symbol.dispose für deterministisches Cleanup.
  • Source Phase Importsimport source zum Laden ohne Auswertung.
  • Deferring Module Evaluationimport defer, vergleichbar zu Lazy-Imports.
  • Decorator Metadata, Atomics.pause, Joint Iteration.

Auf Stage 2.7 liegen u. a. ShadowRealm, Iterator Chunking und Immutable ArrayBuffers. Spannend, aber langfristig sind Records & Tuples (Wert-Objekte mit ===-Vergleich), die Temporal-API als Date-Ersatz, Pattern Matching und der Pipeline-Operator (|>).

Polyfills und Transpilation

Wenn ein Browser ein Feature nicht kennt, hilft eines von zweien:

  • Polyfills ergänzen fehlende Runtime-Methoden zur Laufzeit (z. B. Array.prototype.flat in alten Engines). Standard-Bibliothek dafür ist core-js, automatisch eingespielt durch @babel/preset-env oder swc/preset-env.
  • Transpilation schreibt neue Syntax in alte um (z. B. ?? zu einem Ternary). Hier kommen Babel, swc oder esbuild ins Spiel — Vite und Next.js kapseln das.

Ob beides notwendig ist, haengt vom Browser-Target ab. Eine browserslist-Konfiguration in package.json steuert beide Toolchains:

JSON package.json
{
    "browserslist": [
        "> 0.5%",
        "last 2 versions",
        "not dead",
        "not IE 11"
    ]
}

Für reine Server-Projekte (Node 20+) ist Polyfilling fast nie noetig — die Engine kann schon alles bis ES2024 nativ. Für Browser-Apps haengt es davon ab, wie alt das Target sein darf.

Browser-Support und Baseline

Der Baseline-Standard von web.dev/MDN unterscheidet zwei Stufen:

  • Newly available — in allen Baseline-Browsern (aktuelles Chrome, Edge, Firefox, Safari) verfügbar.
  • Widely available — seit mindestens 30 Monaten in allen Baseline-Browsern.

Stand 2026 gilt grob: ES2022 ist „widely available", ES2023/ES2024 sind „newly available", ES2025 zieht in den nächsten Monaten nach. Die feinkoernige Prüfung erfolgt über caniuse.com oder die MDN-Compat-Tabelle pro Feature.

Wissenswertes zum Release-Modell

TC39 entscheidet per Konsens

Es gibt kein Voting. Eine einzelne Delegation kann ein Proposal blockieren, was selten passiert, aber Konsens erzwingt. Champions verbringen oft Jahre damit, ein Feature über alle Stages zu shepherden — Fortschritt ist kein Selbstläufer, sondern Verhandlung.

Stage 4 ist nicht gleich Browser-Support

Der Spec-Status (TC39) und der Implementierungs-Status (Engines) sind getrennt. Stage-3-Features tauchen oft früher in Engines auf als Stage-4-Features in alten Engines. Für die Praxis zählen MDN/caniuse, nicht die Spec-Edition.

Stage 3 ist sicher mit Polyfill

Spec-Verhalten ist auf Stage 3 eingefroren — nur Bugfixes. Tools wie core-js shippen Polyfills für Stage-3-Proposals oft schon, TypeScript bringt passende Types. Fruehe Adoption ist daher meist risikoarm.

ES2015/ES6 ist der größte Sprung

Alle Editionen seit 2016 sind inkrementell. Wer ES2015 sicher beherrscht — Klassen, Arrow, Module, Promises, Destructuring — versteht 90 Prozent des modernen JavaScript-Codes. Das macht den Einstieg in eine größtenteils stabile Sprache möglich.

Optional Chaining und Nullish Coalescing ersetzen alte Patterns

obj && obj.foo && obj.foo.bar wird zu obj?.foo?.bar. x || default wird zu x ?? default — sicher gegen 0, "" und false. Beide Operatoren sind seit ES2020 Standard und gehoeren in modernen Code wie Atemluft.

Decorators: zwei Welten

Die TS-Legacy-Decorators (experimentalDecorators) sind nicht die JS-Stage-3-Decorators. Die neue Spec hat ein anderes Argumenten-Schema und andere Hooks. Frame­works wie Angular und NestJS migrieren schrittweise; bestehender Code bleibt vorerst auf der Legacy-Variante.

Pipeline-Operator: Hack-Style hat gewonnen

Es gab zwei konkurrierende Vorschlaege: F#-Style (impliziter Wert) und Hack-Style mit %-Placeholder. Der Hack-Style hat sich durchgesetzt und liegt auf Stage 2. Beispiel: value |> doubled(%) |> squared(%).

Temporal ersetzt Date — ergänzt es nicht

Date ist konzeptionell zu kaputt für Reparaturen: mutable, monatzählend ab 0, ohne Zeitzonen. Die Temporal-API bringt PlainDate, ZonedDateTime, Duration, Instant — alles immutable, mit Zeitzonen-Unterstützung. Die Migration wird Jahre dauern, der Schnitt ist gewollt.

Weiterfuehrende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Grundlagen

Zur Übersicht