1997 – 2027

JavaScript Versions

Every public release of ECMAScript — from ES1 in June 1997 through ES2027 (the in-flight 18th edition, with Temporal and explicit resource management) — with ship year and the headline language features per edition. Plus a feature-to-year lookup, an engine-support matrix, and the surrounding history: Brendan Eich's ten-day prototype, the JavaScript / Java naming dispute, the original engine wars, the ES4 collapse, the December 2009 ES5 detente, the June 2015 ES6 watershed, the TC39 stage process, and the Node.js fork-of-V8 lineage.

Era

Pre-Annual — ES1 – ES5.1, 1997–2011, irregular cadence with the ten-year ES4-era edition freeze at the middle
Annual — ES2015 (ES6) onward, year-pinned each June by the Ecma General Assembly

ECMAScript editions are spec versions, not implementations. For per-feature engine support see MDN and caniuse.com — both update on a sub-week cadence. The engine-support matrix below is the high-level "what edition does each major engine fully support" view.

ECMAScript edition table

Edition
ES2027 (18th Ed.)
Annual
2027 (expected)
In-flight 18th Edition — the finished (Stage 4) proposals that carry an “Expected Publication Year” of 2027 in TC39’s finished-proposals list, rather than the 2026 edition. Headlined by Temporal (date/time API replacing Date) and explicit resource management (using / await using), plus Atomics.pause and Joint Iteration (Iterator.zip). All four reached Stage 4 at the March and May 2026 plenaries; Ecma General Assembly ratification of the edition is expected in 2027.
  • Temporal — a complete replacement for Date, the most-anticipated addition since ES2015. Introduces immutable, timezone-aware date/time types: Temporal.PlainDate, Temporal.PlainTime, Temporal.ZonedDateTime, Temporal.Duration, and others. Built-in time zone and calendar support; fully immutable; explicit handling of ambiguous wall-clock times. Reached Stage 4 at the March 2026 TC39 plenary — nine years after the proposal repository opened in March 2017 — with a 2027 publication-year pin. Firefox 139 was the first engine to ship it unflagged (May 2025); Chrome 144 followed (January 2026).
  • Explicit resource management (using / await using) — declares block-scoped variables whose Symbol.dispose / Symbol.asyncDispose method is called automatically on scope exit, whether by normal completion, exception, return, or break. Pairs with DisposableStack and AsyncDisposableStack for managing multiple resources. Eliminates the try/finally boilerplate for file handles, database connections, and similar resources.
  • Atomics.pause() — a hint to the CPU that the current code is in a spin-wait loop, letting the processor optimize power and pipeline behavior on shared-memory busy-waits.
  • Joint IterationIterator.zip / Iterator.zipKeyed for stepping multiple iterables in lockstep, the lazy analog of zipping arrays together.
  • See the TC39 finished-proposals list — these proposals carry an “Expected Publication Year” of 2027, distinguishing them from the 2026-pinned batch below.
  • Status: these proposals are Stage 4 (finished) but carry a 2027 Expected Publication Year, so they group into the in-flight ES2027 edition rather than ES2026. All four cleared Stage 4 in 2026: Temporal at the March 2026 plenary, and Atomics.pause, Joint Iteration and explicit resource management at the May 2026 plenary. Explicit resource management had been conditionally advanced to Stage 4 back in May 2025, pending Test262 coverage and editor sign-off; those conditions took a year to clear. The living standard at tc39.es/ecma262/multipage/ is now the ECMAScript 2027 (eighteenth edition) draft; formal Ecma General Assembly ratification expected 2027.
Edition
ES2026 (17th Ed.)
Annual
Jun 30, 2026
Ratified by the Ecma General Assembly on June 30, 2026 (17th edition). Seven proposals: Map/WeakMap upsert (getOrInsert), JSON.parse source-text access, Iterator Sequencing (Iterator.concat), Uint8Array Base64/hex, Math.sumPrecise, Error.isError, and Array.fromAsync. (Temporal and using are finished but carry a 2027 Expected Publication Year, so they land in ES2027.)
  • Map / WeakMap upsertgetOrInsert and getOrInsertComputed collapse the check-then-insert pattern into one lookup.
  • JSON.parse source-text access — the reviver now receives a context object with context.source, the original token text, enabling lossless round-trips for large numbers; paired with JSON.rawJSON / JSON.isRawJSON on the serialization side.
  • Iterator SequencingIterator.concat(...iterables) chains multiple iterables into one lazy iterator.
  • Uint8Array Base64 & hex — built-in toBase64 / fromBase64 / setFromBase64 plus the matching toHex / fromHex, retiring the btoa / atob string-roundtrip dance.
  • Math.sumPrecise(values) — correctly-rounded summation of an iterable of numbers, avoiding the floating-point accumulation error of a naive .reduce((a, b) => a + b).
  • Error.isError(value) — a reliable cross-realm check for native Error objects, where instanceof Error fails across iframes / VM contexts and Symbol.toStringTag checks can be spoofed.
  • Array.fromAsync(items, mapFn?) — collects an async iterable into an array; the for await...of analog of Array.from.
  • See the TC39 finished-proposals list — these seven proposals carry an “Expected Publication Year” of 2026.
  • Status: Ratified as the 17th Edition of ECMA-262 by the 131st Ecma General Assembly, held in Geneva on June 30, 2026. The published standard is catalogued at ecma-international.org.
Edition
ES2025 (16th Ed.)
Annual
Jun 25, 2025
Iterator helpers; Set methods (union, intersection, difference, …); JSON modules & import attributes; RegExp.escape; Promise.try; Float16Array.
  • Iterator helpersIterator.prototype.{map, filter, take, drop, flatMap, reduce, toArray, forEach, some, every, find} plus the Iterator global. Lazy, composable iterator pipelines without converting to arrays.
  • Set methodsSet.prototype.{union, intersection, difference, symmetricDifference, isSubsetOf, isSupersetOf, isDisjointFrom}. The convenience methods Set has long been missing.
  • JSON modules & import attributesimport data from "./data.json" with { type: "json" }. The standardized form of the older "import assertions" syntax.
  • RegExp.escape(s) — safely escape a string for use in a regex; the missing primitive that has shipped as third-party utility code for two decades.
  • Inline regex modifier flags(?i:...), (?-i:...) for scoped flag changes inside a regex.
  • Promise.try(fn) — wrap a possibly-throwing, possibly-async callback in a single Promise without conditional handling.
  • Float16Array + Math.f16round + DataView.{get,set}Float16 — IEEE 754 half-precision floats; useful for ML inference and color pipelines.
  • Ratified June 25, 2025 by the 129th Ecma General Assembly in Geneva, as ECMA-262 16th Edition.
Edition
ES2024 (15th Ed.)
Annual
Jun 26, 2024
Object.groupBy / Map.groupBy; Promise.withResolvers; resizable ArrayBuffers; RegExp /v flag; well-formed Unicode strings.
  • Object.groupBy(items, fn) and Map.groupBy(items, fn) — the canonical group-by primitive that has shipped as a Lodash _.groupBy utility for a decade.
  • Promise.withResolvers() — returns { promise, resolve, reject }; eliminates the deferred-pattern boilerplate of capturing resolvers from inside the executor.
  • Resizable ArrayBuffers + transferable ArrayBuffersnew ArrayBuffer(n, { maxByteLength: m }), .resize(), .transfer().
  • RegExp /v flag — "Unicode sets" mode with set notation ([\p{L}--\p{ASCII}]) and properties of strings.
  • Well-formed Unicode stringsString.prototype.{isWellFormed, toWellFormed} for surrogate-pair sanity.
  • Atomics.waitAsync; ArrayBuffer.prototype.transferToFixedLength.
  • Ratified June 26, 2024 by the 127th Ecma General Assembly in Geneva, as ECMA-262 15th Edition.
Edition
ES2023 (14th Ed.)
Annual
Jun 27, 2023
Array find-from-last; array by copy (toSorted, toReversed, toSpliced, with); hashbang grammar; Symbols as WeakMap keys.
  • Array find from lastArray.prototype.{findLast, findLastIndex}.
  • Array by copy — non-mutating versions of sort, reverse, splice and a new with method that returns a new array with one element replaced. Long-overdue React-friendly primitives.
  • Hashbang grammar#!/usr/bin/env node as a valid first line of a script.
  • Symbols as WeakMap keys — previously WeakMap keys had to be Objects; now non-registered Symbols are valid too.
  • Ratified June 27, 2023 by the 125th Ecma General Assembly in Geneva, as ECMA-262 14th Edition.
Edition
ES2022 (13th Ed.)
Annual
Jun 22, 2022
Class fields (public, private, static); top-level await; Object.hasOwn; Error.cause; Array.prototype.at; class static blocks.
  • Class fields — public instance fields, private fields with # prefix, public and private static fields, public and private methods. The largest class-syntax expansion since ES6.
  • Top-level await — in module scope, no async wrapper required. Reshapes how module loading composes with async work.
  • Object.hasOwn(obj, prop) — the safe-on-null-proto replacement for Object.prototype.hasOwnProperty.call.
  • Error.causethrow new Error("msg", { cause: original }) for chained errors.
  • Array.prototype.at(i) — supports negative indices (arr.at(-1)).
  • Class static initialization blocks (static { ... }); RegExp /d flag for match indices; private fields presence checks (#field in obj).
  • Ratified by the 123rd Ecma General Assembly in Geneva, which sat June 22–23, 2022, as ECMA-262 13th Edition.
Edition
ES2021 (12th Ed.)
Annual
Jun 22, 2021
Logical assignment (||=, &&=, ??=); String.prototype.replaceAll; Promise.any; numeric separators; WeakRefs.
  • Logical assignment operatorsx ||= y, x &&= y, x ??= y — conditional-assignment shortcuts pairing ES2020's ?? with the standard logical operators.
  • String.prototype.replaceAll(pattern, replacement) — the long-missing form that doesn't require a global regex flag.
  • Promise.any(promises) — resolves on the first fulfilled, rejects with AggregateError if all reject.
  • Numeric separators1_000_000 for readability; works on integers, floats, and BigInts.
  • WeakRefs and FinalizationRegistry — weak references and finalizers, with the explicit caveat in the spec that they're rarely the right tool.
  • Ratified June 22, 2021 by the 121st Ecma General Assembly, held as a virtual meeting, as ECMA-262 12th Edition.
Edition
ES2020 (11th Ed.)
Annual
Jun 16, 2020
Optional chaining (?.); nullish coalescing (??); BigInt; Promise.allSettled; dynamic import(); globalThis; String.prototype.matchAll.
  • Optional chaining (?.) — obj?.prop?.method?.(). Eliminated a generation of "cannot read property of undefined" boilerplate; landed in TypeScript and V8 around the same time.
  • Nullish coalescing (??) — x ?? "default" falls back only on null / undefined, unlike || which falls back on any falsy value.
  • BigInt — arbitrary-precision integers with the 123n literal syntax.
  • Promise.allSettled — like Promise.all but waits for every promise regardless of rejection.
  • Dynamic import() — runtime-resolved modules; the foundation of every modern code-splitting bundler.
  • globalThis — the universal global reference (replaces the window / self / global / this sniffing pattern).
  • String.prototype.matchAll; export * as ns from "..." namespace re-export; for-in mechanics standardized.
  • Ratified June 16, 2020 by the 119th Ecma General Assembly, held as a virtual meeting, as ECMA-262 11th Edition. The single largest "modern dialect" release since ES6.
Edition
ES2019 (10th Ed.)
Annual
Jun 26, 2019
Array.prototype.flat / flatMap; Object.fromEntries; optional catch binding; String.prototype.trimStart / trimEnd; stable Array.sort.
  • Array.prototype.flat(depth) and Array.prototype.flatMap(fn).
  • Object.fromEntries(iter) — the inverse of Object.entries.
  • Optional catch binding — try {} catch {}.
  • String.prototype.{trimStart, trimEnd}; Symbol.prototype.description.
  • Array.prototype.sort required to be stable.
  • Ratified June 26, 2019 by the 117th Ecma General Assembly in Geneva, as ECMA-262 10th Edition.
Edition
ES2018 (9th Ed.)
Annual
Jun 27, 2018
Async iteration / for-await-of; object spread / rest; Promise.prototype.finally; RegExp lookbehind, named captures, /s dotAll, Unicode property escapes.
  • Async iterationfor-await-of, async generators (async function*).
  • Object spread / rest properties{ ...obj }, const { a, ...rest } = obj.
  • Promise.prototype.finally(fn).
  • Major regex expansion: lookbehind (?<=...) / (?<!...), named captures (?<name>...), /s dotAll, Unicode property escapes \p{...}.
  • Template literal revision (drops the well-formedness restriction on cooked strings).
  • Ratified June 27, 2018 by the 115th Ecma General Assembly in Geneva, as ECMA-262 9th Edition.
Edition
ES2017 (8th Ed.)
Annual
Jun 27, 2017
async / await; Object.values / Object.entries; Object.getOwnPropertyDescriptors; string padding; trailing commas in function params.
  • async / await — the syntactic-sugar layer over Promises that reshaped async JavaScript. The most-celebrated post-ES6 addition.
  • Object.values(obj) and Object.entries(obj) — the long-missing siblings to Object.keys.
  • Object.getOwnPropertyDescriptors.
  • String padding: String.prototype.padStart / padEnd.
  • Trailing commas in function parameter lists.
  • Shared memory / Atomics (SharedArrayBuffer, Atomics).
  • Ratified June 27, 2017 by the 113th Ecma General Assembly in Montreux, as ECMA-262 8th Edition.
Edition
ES2016 (7th Ed.)
Annual
Jun 14, 2016
First annual edition. Tiny scope by design: Array.prototype.includes; exponentiation operator **.
  • First annual edition. Deliberately tiny scope to prove out the new "ship-when-ready" cadence after the five-and-a-half-year gap between ES5 (December 2009) and ES6 (June 2015).
  • Array.prototype.includes(value) — clearer than indexOf(x) !== -1; correctly handles NaN.
  • Exponentiation operator **2 ** 10 === 1024; the explicit operator form of Math.pow.
  • Set the template for every annual edition since: small, focused on what reached Stage 4 by the March cutoff, no big-bang feature drops.
  • Ratified June 14, 2016 by the 111th Ecma General Assembly in Montreux, as ECMA-262 7th Edition.
Edition
ES2015 / ES6 (6th Ed.)
Annual
Jun 17, 2015
The watershed. let / const, arrow functions, classes, modules, Promises, template literals, destructuring, default / rest / spread, Map / Set / WeakMap / WeakSet, Symbols, generators, iterators, Proxies.
  • The watershed release of JavaScript. The Harmony track that produced it opened at the August 2008 split that abandoned ES4 and closed here in June 2015 — five and a half years after ES5 (December 2009). The single largest expansion of the language in its history; the "modern JavaScript" era starts here.
  • Lexical scopinglet and const at block scope. Replaces the var-only function-scope model that had defined the language since 1995.
  • Arrow functionsx => x * 2; lexical this.
  • Classes — sugar over the prototype model with extends / super.
  • ES Modulesimport / export as the standard module system, ending the CommonJS / AMD / UMD wars.
  • Promises as a built-in primitive (replacing the proliferation of third-party Promise libraries).
  • Template literals, destructuring, default / rest / spread, Map / Set / WeakMap / WeakSet, Symbols, generators (function*, yield), iterators (for-of), Proxies and Reflect.
  • Tail calls were specified but never widely implemented (Safari is the only engine that ever shipped them).
  • Officially renamed from "ES6" to "ES2015" mid-process, marking the move to year-pin naming. Both names are still in common use; "ES6" is the cultural reference, "ES2015" is the spec name.
  • Ratified June 17, 2015 by the 109th Ecma General Assembly in Montreux, as ECMA-262 6th Edition; Allen Wirfs-Brock was the project editor who carried it to publication.

The ES6 watershed and the move to annual releases — June 2015. Above this line: the Annual era — year-pinned editions ratified each June by the Ecma General Assembly, with the Stage 4 cutoff for inclusion at the March TC39 plenary. Below: the Pre-Annual era — ES1 through ES5.1, 1997 through 2011, irregular cadence with the ten-year ES4-era edition freeze at its middle. The shift to annual editions is the most consequential process change in the language's history; the underlying TC39 stage process and the "what's at Stage 4 in March goes in the June edition" cadence date from this transition.

Edition
ES5.1 (5.1 Ed.)
Pre-Annual
Jun 29, 2011
Editorial alignment with ISO/IEC 16262:2011. No new language features.
  • Editorial revision aligning ECMA-262 with the ISO/IEC 16262:2011 reference; no normative language changes.
  • Adopted June 29, 2011 by the 101st Ecma General Assembly in Divonne, as ECMA-262 5.1 Edition. Ecma's catalogue records only the month; the General Assembly record carries the day.
  • This is the edition that was current for nearly four years — from June 2011 through June 2015 — while the post-ES4 community worked through what would become ES6.
Edition
ES5 (5th Ed.)
Pre-Annual
Dec 3, 2009
Strict mode; native JSON; getter / setter syntax; Object.create, Object.defineProperty; Array iteration methods (forEach, map, filter, reduce).
  • The detente release. Ratified December 3, 2009 by the Ecma General Assembly meeting in Mountain View, California — ten years after ES3, and sixteen months after the August 2008 split that abandoned ES4. The "what we can all agree on" subset that emerged when ES4 was abandoned in 2008 and the committee broke into the ES3.1-becomes-ES5 track and the Harmony-becomes-ES6 track.
  • Strict mode ("use strict") — the opt-in stricter parsing and runtime that has been the foundation of every modern JS toolchain since.
  • Native JSONJSON.parse / JSON.stringify. Replaces the older Crockford json2.js shim that every site had been carrying around.
  • Array iteration methodsforEach, map, filter, reduce, reduceRight, every, some, indexOf, lastIndexOf. Reshaped how JavaScript collections are processed.
  • Property descriptorsObject.create, Object.defineProperty, Object.freeze, getter / setter syntax in object literals.
  • Reserved words allowed as property names; trailing commas in object / array literals.
  • The first ECMAScript edition every major browser eventually implemented in full — though "eventually" meant three and a half years, not months: Safari 6 (July 2012), IE 10 (October 2012), Chrome 23 (November 2012), and finally Firefox 21 (May 2013). The engine wars ended in cross-browser stability around a single spec, but slowly.
Edition
ES3 (3rd Ed.)
Pre-Annual
Dec 1999
Regular expressions; try / catch; do-while; better Unicode handling.
  • Regular expressions as a first-class language feature — literal syntax (/pattern/flags), RegExp object, String-method integration.
  • try / catch / finally — structured exception handling.
  • do-while loops; switch statement standardized; better Unicode handling.
  • The edition that was current for ten years (1999–2009) while ES4 was being debated and ultimately abandoned.
Edition
ES2 (2nd Ed.)
Pre-Annual
Aug 1998
Editorial alignment with ISO/IEC 16262. No new language features.
  • Editorial revision aligning ECMA-262 with the ISO/IEC 16262 standard. No normative language changes.
  • Dated August 1998 by the published standard's cover, by the standard's own adoption statement (“adopted as 2nd Edition of ECMA-262 by the ECMA General Assembly in August 1998”), and by Ecma's ECMA-262 catalogue entry. The June 1998 date in wide circulation isn't a folk error — it comes from ECMA-262's own Introduction, which says the General Assembly of June 1998 approved the second edition, and that paragraph is still carried verbatim in the living standard today. Approval in June, publication in August; this row uses the published date.
Edition
ES1 (1st Ed.)
Pre-Annual
Jun 1997
First standardized edition. The Netscape JavaScript / Microsoft JScript common subset, formalized at Ecma International.
  • The first standardized edition of the language. Ratified by Ecma International in June 1997 as ECMA-262, derived from Netscape JavaScript 1.1 and Microsoft JScript with the convergent subset both engines implemented.
  • Brendan Eich's original prototype — “Mocha” in his own account — dated to May 1995 at Netscape; Microsoft's reverse-engineered JScript shipped in Internet Explorer 3.0 in August 1996; work on the standard began at Ecma International in November 1996 with the first TC39 meeting, and Ecma's own twentieth-anniversary note records that the General Assembly approved the standard in June 1997 — seven months later — leaving some editing items and the final choice of the name “ECMAScript” to September 1997.
  • The edition number is "ECMAScript Edition 1" — the prefix "ES" became conventional only later.
  • The "ECMAScript" name was a compromise — "JavaScript" was a Sun trademark licensed to Netscape; "JScript" was Microsoft's preferred name for its implementation. The standards body needed a vendor-neutral term, and "ECMAScript" was the result.

Each row anchors as #es-YYYY for annual editions (e.g. #es-2025) or #esN for pre-annual editions (#es5, #es3, #es1). The TC39 finished-proposals list at github.com/tc39/proposals/blob/main/finished-proposals.md is the authoritative source for what landed in which edition.

Feature → ES year

Inverse of the table above — people search both "what's in ES2024" and "when did optional chaining ship". This curated list answers the second question at a glance for the high-search-volume features.

let / const, arrow functions, classes, modules, Promises, template literals, destructuring, Map / Set, generators, Proxies
Array.prototype.includes, exponentiation **
async / await, Object.values / entries, string padding
Async iteration / for-await-of, object spread / rest, regex lookbehind & named captures
Array.flat / flatMap, Object.fromEntries, optional catch binding, stable sort
Optional chaining ?., nullish coalescing ??, BigInt, dynamic import(), globalThis, Promise.allSettled
Logical assignment (||= &&= ??=), String.replaceAll, Promise.any, numeric separators, WeakRefs
Class fields (public / private / static), top-level await, Object.hasOwn, Array.at, Error.cause, class static blocks, RegExp /d
Array find from last (findLast, findLastIndex), array by copy (toSorted, toReversed, toSpliced, with), hashbang grammar, Symbols as WeakMap keys
Object.groupBy / Map.groupBy, Promise.withResolvers, resizable ArrayBuffers, RegExp /v flag, well-formed Unicode strings
Iterator helpers, Set methods (union, intersection, difference, …), JSON modules & import attributes, RegExp.escape, inline regex flags, Promise.try, Float16Array
Map / WeakMap upsert (getOrInsert), JSON.parse source-text access (JSON.rawJSON), Iterator Sequencing (Iterator.concat), Uint8Array Base64 / hex, Math.sumPrecise, Error.isError, Array.fromAsync
Temporal (date/time API replacing Date)
Explicit resource management (using / await using)
Strict mode, native JSON, Array iteration methods (forEach, map, filter, reduce), Object.create, getter / setter syntax
Regular expressions, try / catch, do-while

Curated subset of the high-search-volume features. For the full per-edition feature list, click the corresponding row in the table above. For per-feature engine support, see MDN and caniuse.com.

Engine support matrix

High-level "what edition does each major engine fully support" view. Per-feature status is on MDN and caniuse.com — both update on a sub-week cadence and are the canonical sources.

Engine ES5 (2009) ES2015 (ES6) ES2020 ES2024 ES2025
V8 (Chrome / Node / Edge) Chrome 23 (Nov 2012) Chrome 51 (May 2016) Chrome 80 (Feb 2020) Chrome 119 (Oct 2023) Chrome 136 (Apr 2025)
SpiderMonkey (Firefox) Firefox 21 (May 2013) Firefox 54 (Jun 2017) Firefox 74 (Mar 2020) Firefox 145 (Nov 2025) Firefox 138 (Apr 2025)
JavaScriptCore (Safari / WebKit) Safari 6 (Jul 2012) Safari 10 (Sep 2016) Safari 14 (Sep 2020) Safari 17.4 (Mar 2024) Safari 26 (Sep 2025)
Chakra (legacy Edge / IE11) IE 10 (Oct 2012) Edge 15 (Apr 2017) EOL EOL EOL

For the annually-pinned editions, each cell is the engine version in which the last feature of that edition landed — a max() over the edition's entries in the TC39 finished-proposals list, looked up in MDN's compat-data. The ES5 and ES2015 columns predate that list, so they use caniuse's threshold instead: the first version at which the engine cleared 95% of the edition (proper tail calls excepted — only Safari ever shipped them). Cells are per-edition, not cumulative, so a lone straggler can push one edition's cell past a later edition's: Firefox reached full ES2025 at 138 but only cleared ES2024 at 145, because Atomics.waitAsync landed in Firefox 145 (November 2025), sixteen months after the rest of that edition had cleared in Firefox 128 (July 2024). The other recent stragglers are RegExp.escape (Chrome 136), import attributes (Firefox 138), and inline regex modifiers (Safari 26); for ES2020 it was optional chaining and nullish coalescing (Chrome 80, Firefox 74) and BigInt (Safari 14). Editions routinely reach full support before ratification — Stage 4 requires two shipping implementations — which is why Chrome cleared ES2024 in Oct 2023 and ES2020 in Feb 2020. Chakra was discontinued when Microsoft adopted Chromium / V8 for Edge in January 2020; the row remains for historical context.

The 1995 origin and Brendan Eich's ten-day prototype

JavaScript was prototyped by Brendan Eich at Netscape over ten days in May 1995. Netscape wanted a programming language embedded in HTML, in source form — by Eich's own account that push came from client engineering management (Tom Paquin, Michael Toy, Rick Schell) together with Marc Andreessen, so it was never a case of Eich selling the idea upward. The narrower constraint that the language must "look like Java" was a separate diktat from upper engineering management, and it is the one that ruled out Scheme along with Perl, Python and Tcl. Sun's Bill Joy was, in Eich's telling, the champion on the Java side of an easy-to-use scripting language as a companion to Java. Eich had been recruited to Netscape on the promise of "doing Scheme" in the browser; once the look-like-Java constraint came down, he did the design work in ten days against a hard ship deadline. The prototype was named Mocha in Eich's own account, and the language reached the public as JavaScript — a marketing move to capitalize on Java's mindshare, not a technical lineage statement. The widely-repeated intermediate name LiveScript is retrospective usage: it appears in none of Netscape's 1995 press releases, including the four issued the day Navigator 2.0 was announced. The naming and the shipping are two separate dates, and so are the announcement and the download — all three get collapsed onto one. Netscape introduced Navigator 2.0 on September 18, 1995, and that day's press release says the public beta “will be available next week” — it does not name a scripting language at all. The JavaScript name first appears in the joint Netscape / Sun announcement of December 4, 1995, which places the first release in “the beta version of Netscape Navigator 2.0, which is currently available for downloading” — giving no beta number, and describing JavaScript as a new announcement rather than a rename. Which beta first carried which name is not settled by Netscape's own record.

Eich's design under the ten-day deadline produced both the language's strengths (first-class functions, prototype-based objects, dynamic typing, garbage collection) and most of its long-running quirks (the == coercion rules, typeof null === "object", automatic semicolon insertion, the var function-scope model). Many of the language's modern revisions are about working around or around the original ten-day decisions. Eich has been candid about this in talks and interviews: the brief said "make it look like Java," the deadline was non-negotiable, and the design committee was him.

JScript and the original engine wars

Microsoft reverse-engineered JavaScript and shipped JScript in Internet Explorer 3.0 in August 1996. The two implementations diverged immediately on subtle semantic edges; web developers spent the next decade writing browser-specific code paths because the same JavaScript could behave differently between Netscape and IE. Netscape submitted the language to Ecma International in November 1996 to produce a vendor-neutral standard; the result was ECMAScript Edition 1 in June 1997. The "ECMAScript" name was the standards-body compromise — "JavaScript" was a Sun-trademarked name licensed to Netscape, "JScript" was Microsoft's preferred name, and Ecma needed something neither side could veto.

The ES4 collapse (2003–2008) and the ten-year edition freeze

After ES3 in December 1999, the TC39 committee began work on a much more ambitious ECMAScript 4 — classes, packages, namespaces, optional static typing, generators, an enhanced type system. Mozilla and Adobe (using their ActionScript 3.0 implementation, which was already a partial ES4) backed the design; Microsoft and Yahoo argued ES4 was too ambitious, would fragment the language, and risked breaking the web. The argument ran for years.

The committee deadlocked. In August 2008, after multiple failed attempts at consensus, TC39 split the work into two tracks: a small editorial-and-cleanup release that would become ES5 (December 2009), and an ambitious longer-horizon project codenamed Harmony that would eventually ship as ES6 / ES2015 in June 2015. ES4 itself was abandoned. Most of its design ideas survived into ES6 and beyond — classes, modules, destructuring, default parameters — but the ten-year gap with no new edition at all — December 1999 to December 2009 — is the largest in the language's history and shaped how every TC39 process decision since has been made (smaller scope, shorter cycles, Stage-gated proposals, no big-bang releases).

The TC39 stage process

The post-ES6 TC39 process is structured around six stages for every proposed language addition — a strawperson stage plus five maturity stages. The committee has to approve every advancement:

  • Stage 0 — Strawperson. Any TC39 delegate, or a non-delegate registered through Ecma International, can put an idea in the conversation. No acceptance criteria at all.
  • Stage 1 — Proposal. A champion takes ownership, the committee accepts the problem is worth solving, and a public repository exists describing the problem and the general shape of a solution. The work of the stage is designing that solution.
  • Stage 2 — Draft. The committee has chosen a preferred solution and there is initial spec text covering the major semantics — placeholders and TODOs still allowed. The work is refining details (property names, ordering of observable effects, invalid inputs) and producing throwaway polyfills to pressure-test the design.
  • Stage 2.7 — Testing. Spec text is complete and both the assigned reviewers and the editor group have signed off; the work is building a rigorous Test262 suite to validate it. Added to the process document in December 2023 — it splits apart the two things Stage 3 previously meant at once, "the design is finished" and "engines should start shipping it."
  • Stage 3 — Candidate. Recommended for implementation: the tests exist, and engines are expected to ship the feature and report back web-compatibility or integration problems. Changes at this point come from the field, not from the committee. Most TC39 features that ship in any given year were at Stage 3 the year before.
  • Stage 4 — Finished. Two compatible implementations pass the Test262 acceptance tests, there is significant in-the-field experience, and the integrated spec-text pull request has editor-group sign-off. The March TC39 plenary is the cutoff for the June ratification. Advancement is sometimes granted conditionally, pending test coverage or editor sign-off, and those conditions can take a year to clear — explicit resource management was conditionally advanced in May 2025 and only cleared unconditionally in May 2026.

The cadence: candidate draft cut on February 1 → Stage 4 proposals folded in at the March plenary → Ecma General Assembly ratifies in June → spec snapshot pinned at tc39.es/ecma262/<year>/. A modern edition is a handful of finished proposals rather than a big-bang release. Per-stage entrance criteria are in the TC39 process document.

The engine lineage

Four major JavaScript engines have shaped the modern landscape:

  • SpiderMonkey (Mozilla) — the original engine, descendant of Brendan Eich's 1995 prototype. Written in C++ with a JIT (IonMonkey, then WarpMonkey). Powers Firefox.
  • V8 (Google) — built by Lars Bak and a small team in Aarhus, Denmark. Google hired Bak in the autumn of 2006 for a then-secret browser project; with no Google office in Aarhus, the work started in an outbuilding on his farm, and the team moved into a Google building there only once it had grown. Open-sourced the day Chrome launched — September 2, 2008 — under BSD, JIT-driven (TurboFan, Maglev, Sparkplug), the engine that turned JavaScript performance into a serious cross-vendor competition. Now powers Chrome, Node.js, Microsoft Edge (since January 2020), Opera, Brave, Cloudflare Workers, Deno, and most of the rest of the modern V8-derived ecosystem.
  • JavaScriptCore / Nitro (Apple) — powers Safari and the WebKit web view used in every iOS app. Less aggressively marketed than V8 but technically peer; the FTL JIT and B3 backend produce competitive numbers.
  • Chakra (Microsoft) — powered Internet Explorer 9 through 11 and the original (2015–2020) Edge. Discontinued when Microsoft adopted Chromium / V8 for Edge in January 2020. The engine wars effectively ended at that point: every major modern browser uses a V8 / SpiderMonkey / JavaScriptCore engine, and V8 has the largest share by a wide margin.

Smaller specialized engines exist alongside: Hermes (Meta, for React Native), QuickJS (Fabrice Bellard's tiny embeddable engine), Boa (Rust implementation), engine262 (an implementation of ECMA-262 written in JavaScript, aimed at 100% spec compliance and introspection rather than speed — the practical way to actually run a proposal before any production engine has it; it is a community project, not an official TC39 deliverable).

Node.js — JavaScript on the server (2009–)

Ryan Dahl announced Node.js at JSConf EU on November 8, 2009 — V8 (Google's then-newish JavaScript engine) wrapped in an event-loop runtime designed for non-blocking I/O. The pitch: write the same language on both ends of a network connection, with concurrency handled by the event loop instead of by threads. The combination caught on faster than anyone expected. Within five years, Node.js had reshaped the back-end JavaScript ecosystem, the browser-tooling ecosystem (every modern frontend toolchain runs on Node), and effectively created the npm package-management universe, whose registry now holds more than five million packages. Dahl handed off Node.js to the community and OpenJS Foundation; he later founded Deno in 2018 as an attempt to retry the design with the lessons learned. Bun (Jarred Sumner, 2022) is a third attempt with a Zig-based runtime, JavaScriptCore instead of V8, and a much faster cold-start path.

People who actually shaped JavaScript / ECMAScript

Origin and language design: Brendan Eich (Netscape, 1995; the ten-day prototype; later co-founded Mozilla and Brave); Marc Andreessen, with client engineering managers Tom Paquin, Michael Toy and Rick Schell, on the decision to embed a programming language in HTML at all; Bill Joy (Sun), whom Eich credits as the champion on the Java side of a scripting-language companion to Java. Eich attributes the "must look like Java" constraint itself to unnamed upper engineering management rather than to any one person — a distinction worth keeping, because it is routinely collapsed into a single origin story.

TC39 chairs and editors: Allen Wirfs-Brock, named in the spec itself as ECMA-262 6th Edition project editor — the one who carried ES2015 to publication; Brian Terlson, project editor from the 7th Edition (ES2016) through ES2019. The current ECMA-262 editor group is Ron Buckton, Michael Ficarra, Richard Gibson, Linus Groh, Shu-yu Guo, and Nicoló Ribaudo; Ecma lists the TC39 chair group as Chris de Almeida and Rob Palmer. For proposal champions the authoritative record is the champion column of the finished-proposals list itself, which names them per proposal rather than by reputation; recurring names across many editions include Jordan Harband, Mathias Bynens, Kevin Gibbons, Daniel Ehrenberg, Michael Ficarra, Shu-yu Guo and Rick Waldron, with Mark Miller championing WeakRefs.

Engines: Lars Bak (V8 architect, ex-Sun HotSpot lineage), Andreas Rossberg (formerly V8's JavaScript language-team lead at Google; WebAssembly co-designer and spec author), the Mozilla SpiderMonkey lineage that descends from Eich's original engine, Filip Pizlo and the JavaScriptCore / FTL JIT team. Server-side / runtimes: Ryan Dahl (Node.js, Deno), Jarred Sumner (Bun).

Sources: TC39 finished-proposals; ECMA-262 standards page; TC39 spec snapshots; MDN web docs (CC-BY-SA); caniuse.com (CC-BY); Brendan Eich's history posts and 2008 JSConf talk; TC39 meeting notes. Cross-references: TypeScript Versions. Last updated September 2026.

Mungomash LLC · More data pages