Skip to content
JavaScript js getting-started 4 min read

History & ECMAScript Versions

JavaScript has come a long way from a language hacked together in ten days to the most widely deployed programming language on the planet. Understanding where it came from — and how the ECMAScript standard now evolves on a predictable yearly schedule — helps you read code from any era, choose language features with confidence, and make sense of terms like “ES6” and “modern JS” that appear everywhere in tutorials and job postings.

The birth of JavaScript (1995)

JavaScript was created by Brendan Eich at Netscape in 1995, reportedly in about ten days, to add interactivity to web pages in the Netscape Navigator browser. It was first shipped under the name LiveScript, then quickly rebranded to JavaScript as a marketing move to ride the popularity of Java — despite the two languages being almost entirely unrelated.

Microsoft soon reverse-engineered it as JScript for Internet Explorer. With two competing, slightly incompatible implementations, the web needed a neutral specification.

ECMAScript: the standard behind the language

To prevent fragmentation, the language was submitted to Ecma International for standardization. The resulting specification is called ECMAScript (often abbreviated ES), defined in the document ECMA-262. “JavaScript” is the popular name for the language; “ECMAScript” is the formal standard that browsers and runtimes implement.

Tip: When people say “ES6” they mean a version of the ECMAScript spec, not a separate language. JavaScript engines such as V8 (Chrome, Node.js), SpiderMonkey (Firefox), and JavaScriptCore (Safari) implement the ECMAScript spec.

The first edition landed in 1997. ES3 (1999) added regular expressions and try/catch and became the long-lived baseline for years. ES4 was famously abandoned for being too ambitious.

The ES5 era (2009)

ES5 (2009) was a major, stabilizing release. It introduced strict mode ("use strict"), native JSON support, property descriptors, and array iteration helpers — features that defined “professional” JavaScript for the better part of a decade.

"use strict";

const numbers = [1, 2, 3, 4];
const doubled = numbers.map(function (n) {
  return n * 2;
});

console.log(JSON.stringify(doubled));

Output:

[2,4,6,8]

ES2015 (ES6): the pivotal release

ES2015, universally known as ES6, was the biggest leap in the language’s history. It modernized JavaScript with let/const, arrow functions, classes, template literals, destructuring, default and rest parameters, modules (import/export), promises, and much more.

const greet = (name = "world") => `Hello, ${name}!`;

class Counter {
  #count = 0;
  increment() {
    return ++this.#count;
  }
}

const counter = new Counter();
counter.increment();
console.log(greet("DevCraftly"), counter.increment());

Output:

Hello, DevCraftly! 2

ES6 was so transformative that the community split the language’s mental timeline into “before” and “after.” This is the origin of the phrase “ES6+” — meaning ES2015 and everything that followed.

The yearly release cadence (ES2016+)

After ES6, the TC39 committee (the group that governs the standard) adopted a yearly release cadence. Instead of giant, multi-year releases, the spec now ships every June with whatever features have reached Stage 4 of the proposal process. Releases are named by year: ES2016, ES2017, ES2018, and so on.

This is why you rarely hear “ES7” or “ES8” anymore — year-based names (ES2016, ES2017) are the official convention.

Notable versions and headline features

VersionYearHeadline features
ES52009Strict mode, JSON, Array iteration methods
ES2015 (ES6)2015let/const, arrow functions, classes, modules, promises
ES20162016Array.prototype.includes, exponentiation operator **
ES20172017async/await, Object.entries, string padding
ES20182018Rest/spread for objects, async iteration
ES20192019Array.prototype.flat, Object.fromEntries
ES20202020Optional chaining ?., nullish coalescing ??, BigInt
ES20212021String.prototype.replaceAll, logical assignment ??=
ES20222022Top-level await, class fields, Array.prototype.at
ES2023+2023+Array find-from-last, immutable array methods, and more

A taste of the modern syntax that the post-2015 cadence delivered:

const user = { profile: { name: "Ada" } };

// Optional chaining (ES2020) + nullish coalescing (ES2020)
const city = user?.profile?.address?.city ?? "Unknown";

// async/await (ES2017)
async function loadUser(id) {
  const res = await fetch(`https://api.example.com/users/${id}`);
  return res.json();
}

console.log(city);

Output:

Unknown

What “modern JavaScript” means

“Modern JavaScript” (or “ES6+”) loosely refers to the idiomatic style enabled by ES2015 and later: const/let instead of var, arrow functions, modules, async/await, and strict equality. Today every evergreen browser and current Node.js version supports these features natively, so for most projects you can write modern syntax directly.

Gotcha: A new spec edition doesn’t instantly mean universal support. When targeting older environments, tools like Babel transpile modern syntax down to older ECMAScript, and resources like caniuse.com and the MDN compatibility tables tell you what each engine actually supports.

Best practices

  • Write to a spec version, not a tutorial’s age — prefer ES2020+ syntax (optional chaining, nullish coalescing) on modern targets.
  • Use year-based names (ES2017, ES2022) in writing; reserve “ES6” for the well-known ES2015 milestone.
  • Check caniuse.com and MDN before relying on the newest features in browser code.
  • Reach for Babel (or a bundler that includes it) only when you genuinely need to support older runtimes.
  • Default to const, fall back to let, and avoid var — it predates block scoping and causes subtle bugs.
  • Track proposals at the TC39 GitHub repo if you want to see what’s coming before the next June release.
Last updated June 1, 2026
Was this helpful?