
Ask how JavaScript actually works and you will usually get one of two answers: a tour of the warts, or a tour of the engine. Both are incomplete, because neither explains why the warts and the engine are the same story. The language was prototyped in roughly ten days in May 1995. The engineering that made it survivable — tiered compilation, a specification that can evolve on a schedule, a committee that can retreat — arrived two decades later. Almost everything strange in between is downstream of one constraint that nobody ever voted on and everybody obeys: you may never break the web.
That constraint is not a slogan. It is written into the standard as normative text, it has a bespoke internal slot in the type system serving exactly one object, and it has made the committee refuse a bug fix that would have broken nothing. It is also why JavaScript repays study by anyone maintaining a long-lived interface: it is the largest working example on earth of evolving a specification with billions of live dependents and no way to ship a breaking change. This is the reference article for a fourteen-part series, and it runs chronologically — from a ten-day prototype to a seventeenth edition — pointing at the pieces that own each layer in depth.
The Ten Days Produced a Compiler, Not a Toy
Start with the sentence everybody misuses. It is Brendan Eich’s own, from his blog on 21 June 2011:
“As you may know, I wrote JavaScript in ten days.”
It is true, self-reported, and repeated by its author for decades. The mistake is not believing it — it is believing it describes JavaScript. It describes a prototype, codenamed Mocha, built alone in early-to-mid-May 1995. Wirfs-Brock and Eich’s peer-reviewed history, JavaScript: The First 20 Years (HOPL 2020, 189 pages, free), is candid about the precision available: there is no known record of the dates, and Eich’s own recollection is May 6–15. Treat any tighter range as unsourced.
What those ten days produced matters far more than the calendar, and here the folk version is wrong in an interesting direction. From the same 2011 post:
“That was 1995. Engine prototype took ten days in May. Bytecode compiler and interpreter from the start, because Netscape had a server-side JS product in the works. The rest of the year was browser integration, mainly what became known as “DOM level 0”.”
A bytecode compiler and an interpreter — not a tree-walking toy — because Netscape LiveWire, a server-side JavaScript product, was counting on embedding the language before it had been prototyped. The HOPL paper corroborates this from the other side of the deal: bytecode was a LiveWire requirement, not an implementer’s preference. Two independent accounts, twenty-five years apart, agree that server-side JavaScript shaped the implementation on day one — thirteen years before anyone thought that idea was novel.

Two corollaries follow. First, the author’s own accounting of the proportions is in that same passage — “The rest of the year was browser integration” — so the sprint was the opening move of about eight further months, and what determined the shipped feature set was an August 1995 feature freeze forced by Navigator’s release schedule. JavaScript 1.0, shipped March 1996, had no array or object literals, no regular expressions, no ===, no switch, no try/catch, no function expressions, and no user access to prototype.
Second, the ten-day source tree did not survive eighteen months. In late 1996 Eich rewrote it, and said why:
“So I actually stayed home for two weeks to rewrite Mocha as the codebase that became known as SpiderMonkey, mainly to get it done (no other way), also to go on a bit of a strike against the Netscape management team that was still underinvesting in JS.”
SpiderMonkey — still shipping in Firefox today — is that rewrite, not the 1995 tree carried forward. True in authorship and spirit, false in the literal sense in which it is usually stated.
The name is its own trap, because the popular version has the causality backwards. The widely repeated line that renaming to “JavaScript” was a scramble in reaction to Java appears on Eich’s blog inside a reader’s comment, not in his text — which was correcting that very impression. The HOPL paper goes further: Marc Andreessen proposed the codename “Mocha” already hoping the language would be renamed “JavaScript” once the Sun deal closed. There was no reaction to scramble from; the destination was chosen with the codename.
| Name | In use | Chosen by | Why it ended |
|---|---|---|---|
| Mocha | May–mid 1995 (internal) | Marc Andreessen, expecting the rename | Netscape marketing disliked it and cited trademark worries |
| LiveScript | Navigator 2.0 beta, Sept–Nov 1995 (public) | Netscape | Placeholder while the Sun licence was negotiated |
| JavaScript | 4 December 1995 onward | Netscape and Sun, joint press release | Still the name everyone uses; the trademark is not Netscape’s |
| ECMAScript | 1997 onward (the standard) | TC39, by elimination | Sun would not license “JavaScript” to a standards body; Netscape would not transfer “LiveScript” |
That fourth step is the one almost nobody knows. When the committee needed a name for the specification it could have neither of the two that existed. “ECMAScript” is the leftover placeholder that stuck, and Eich’s own verdict on it, quoted in the HOPL paper, is that it was always an unwanted trade name that sounds like a skin disease.
The Standards Body That Numbered an Edition It Never Published
Load Ecma’s own page for ECMA-262 and scroll to the archive list. Between the third edition and the fifth there is a row with no download link:
ECMA-262, 4th edition (not existing)
with, in the file column, No file available. Most standards bodies would quietly skip a burned number. Ecma kept the row and explained it higher up the same page:
“Please note that for ECMAScript Edition 4 the Ecma standard number “ECMA-262 Edition 4” was reserved but not used in the Ecma publication process. Therefore “ECMA-262 Edition 4” as an Ecma International publication does not exist.”
A standards body listing a numbered edition of its flagship standard and stating that it does not exist is not an archival quirk. It is scar tissue, left visible in 2026. The specification itself narrates the same failure in one clinical sentence in its Introduction:
“Significant work was done to develop a fourth edition of ECMAScript. However, that work was not completed and not published as the fourth edition of ECMAScript but some of it was incorporated into the development of the sixth edition.”
Put the dates next to each other and the shape of the argument appears.

| Edition | Published | Gap since previous |
|---|---|---|
| 1st | June 1997 | — |
| 2nd | August 1998 | 14 months |
| 3rd | December 1999 | 16 months |
| 4th | never — “(not existing)” | — |
| 5th | December 2009 | 120 months |
| 5.1 (Ecma’s own page says “5.1th edition”) | June 2011 | 18 months |
| 6th (ES2015) | June 2015 | 48 months |
| 7th–16th | June 2016 → June 2025 | 12 months each |
| 17th — ECMAScript 2026 | June 2026 — current | 12 months |
(Edition dates from Ecma’s archive page, checked 2026-09-09.)
Three editions in thirty months, then one edition in ten years. The first three were produced by a committee racing a browser war. The gap is what happened after the war ended, the winner stopped caring, and the committee that remained could not agree on what to do next — during precisely the decade in which JavaScript became the most deployed runtime on the planet.
Both Camps Wanted a Fourth Edition
The folk telling of ES4 is a personality clash: visionaries wanted to modernise the language, Microsoft blocked them. That version is wrong about the disagreement, and the correction comes from the opposing camp’s own paper, which is sitting in Ecma’s public document archive.
Ecma/TC39-TG1/2007/042, Microsoft’s position statement of 7 November 2007, says this on its own second page:
“The web needs a 4th Edition of the ECMAScript Specification that codifies conventional usage on the web, corrects known issues, and provides innovative solutions to real web development problems.”
Both camps wanted a fourth edition. Neither got one. The number was burned by a disagreement about what it should contain, not whether to have one. The same paper is equally direct about the limit of its agreement — “Microsoft agrees that it is time to evolve the ECMAScript standard, but we do not see any need or justification for a radical redesign of the language” — and it ranks four tenets in priority order, the first of which is the constraint this whole article is about:
“Ensure Stability of the existing web platform ecosystem. The evolution of ECMAScript must give highest priority to ensuring continuing function of existing web content and applications.”
That is you may never break the web, written down as committee policy in November 2007.

| The ES4 position | The ES3.1 position | |
|---|---|---|
| Backers | Adobe, Mozilla, and the project editor Lars T Hansen | Microsoft, with Yahoo! and others |
| What it was | Classes, namespaces, packages, optional static types — already shipping as ActionScript 3 | Specify what browsers had already converged on, then extend |
| Evidence base | A machine-checkable reference implementation written in Standard ML | Fifteen years of deployed pages and de facto interoperability |
| Stated risk | The language could not express programming in the large | Unintended feature interactions could break pages that use none of the new features |
| Outcome | Draft 1 dated 16 May 2008, Draft 2 dated 11 July 2008, submission targeted for October 2008 — abandoned | Published December 2009, as the 5th edition, not as “3.1” |
Side by side, the two positions share more than either would have admitted. Both wanted a fourth edition. Both put backward compatibility in their stated goals — ES4’s Draft 1 opens its statement of themes with compatibility, not innovation. Both thought the third edition was inadequate. They disagreed about sequencing and risk, which is an ordinary engineering disagreement, and it deadlocked a standards body because the body had no mechanism for resolving it.
There was also a structural reason the fight had to be zero-sum, and Eich named it at the time: Ecma had no provision for minor releases, so any “ES3.1” the committee approved would inevitably be given a whole edition number. The two camps were fighting over a single indivisible resource — the next edition number. Cheap version numbers de-escalate; scarce ones do the opposite.
The deadlock ended through machinery rather than persuasion. The Ecma General Assembly split the old committee in December 2007; the arguing task group was reconstituted as TC39 itself in January 2008; and the chair moved from Eich, serving ad interim, to John Neumann — jointly nominated by Microsoft and Adobe. Then came Oslo, at the end of July 2008.
And here is a sourcing trap worth internalising, the same shape as the naming myth one level up. The most-quoted justification for what was cut is Eich’s, from his es-discuss message of 13 August 2008:
“Some ES4 proposals have been deemed unsound for the Web, and are off the table for good: packages, namespaces and early binding.”
The string “unsound” appears zero times in Ecma’s own press release and zero times in the accompanying Harmony white paper, the two documents describing the same decision — I checked both PDFs directly on 2026-09-09. Ecma’s own wording is flat and administrative:
Remove from consideration the ES4 concepts of “packages,” “namespaces” and “early binding”
Eich is a participant, and a participant’s characterisation of a committee decision is not the committee’s. Attribute it to him, dated, or use Ecma’s words.
The Train That Replaced the Fight
What TC39 built afterwards is the most underrated piece of engineering in this whole story, because it is a governance design aimed squarely at making the ES4 deadlock structurally impossible.
The TC39 process document says, verbatim: “There are six stages: a strawperson stage and five maturity stages.” They are 0, 1, 2, 2.7, 3, and 4 — and any article you read describing “stages 0 through 4” is describing the process as it existed before 1 December 2023, when Stage 2.7 was added. That stage exists to force a design to be tested before it is frozen, which is a direct governance response to the class of failure the previous section describes.
Three clauses carry the weight:
- Stage 3 exists partly to discover “web incompatibilities” — the process document names them, by name, as a licensed reason to change a nearly-final design.
- Stage 4 requires “Two compatible implementations which pass the Test262 acceptance tests”. The committee cannot bless a design into existence; someone must have built it twice, compatibly. This is the cheapest available protection against specifying fiction, and it is exactly what the ES4 process — with one reference implementation — did not have.
- There is a defined path backwards: “The committee does not have an established concept of a rejected proposal–it is always possible for the champion to make changes and come back to ask for consensus.” (The double hyphen is the document’s own.)

The deepest change, though, is what an edition number now means. Editions 1 through 5 were events: a release was a negotiation about scope, so scope was worth fighting over, and a fight could stop the release. Since ES2016 the release is a cadence — one edition every June, scope being whatever reached Stage 4 by March. The specification states it plainly: “ECMAScript 2016 was the first ECMAScript edition released under Ecma TC39’s new yearly release cadence and open development process.” A departing train cannot be held hostage. If your proposal is not ready, it takes the next one, in twelve months.
One practical consequence, and it catches working engineers constantly. tc39.es/ecma262/ is the living draft, not the published edition. Fetched on 2026-09-09 its title reads ECMAScript® 2027 Language Specification, and it contains the UsingDeclaration grammar symbol 149 times. The dated snapshot tc39.es/ecma262/2026/ — the seventeenth edition, published June 2026 — contains it zero times. Explicit resource management (using / await using) is in the draft and is not in ES2026; TC39’s own tracker gives it an expected publication year of 2027. If you need to answer “is this in ES20XX,” cite the dated snapshot. The undated URL will confidently tell you about next year.
The Bet That Made It Fast: Speculate, and Keep a Way Back
None of the above made JavaScript fast. That was a different discipline, and it reduces to one bet: you cannot know the types ahead of time, so guess from what has already happened, compile fast code that assumes the future resembles the recent past, and keep a correct, slower path to fall back to when the guess is wrong. A property access that keeps seeing the same object shape skips the general lookup machinery; objects built the same way share a hidden class the engine can bet on; and when a baked-in assumption fails, the engine deoptimises — bails out of the optimised machine code mid-function and reconstructs the state the slower tier needs. None of it was invented for JavaScript: monomorphic inline caching is Deutsch and Schiffman’s 1984 Smalltalk-80 work, polymorphic inline caches and the “maps” that became hidden classes came out of the Self group at Sun and Stanford in 1989 and 1991, the same people went on to build the HotSpot JVM, and Lars Bak went from Self to leading V8.
V8’s own account of the moment the modern pipeline landed, from its blog of 15 May 2017:
“For the first time, Ignition and TurboFan are used universally and exclusively for JavaScript execution in V8 v5.9. Furthermore, starting with v5.9, Full-codegen and Crankshaft, the technologies that served V8 well since 2010, are no longer used in V8 for JavaScript execution, since they no longer are able to keep pace with new JavaScript language features and the optimizations those features require.”
Note what killed Crankshaft: not hardware, but the language moving out from under it. V8 has since retired a second optimiser’s internals for an entirely different reason — it left the Sea of Nodes in March 2025 on maintenance cost, reporting that “compile time got divided by 2” — and the article on V8 in this series is where those two very different funerals get compared properly.

Do not read any of this as triumph. Speculation is bought with three currencies: memory, because compiled code, feedback vectors and several tiers of the same function stay resident; warm-up, because peak speed only exists once enough profile data has accumulated to justify the expensive compile; and unpredictability, because identical source runs at very different speeds depending on which shapes showed up first at each call site — and the engine will not tell you when it drops you back down.
And V8 is not “the JavaScript engine.” SpiderMonkey and JavaScriptCore are real, shipping, independently engineered and structurally different; JavaScriptCore’s lineage runs through KJS and Konqueror and touches none of Eich’s code. Anyone who writes “the engine” and means V8 has already made an error.
Annex B: The Standard Admitting It in Its Own Words
Here is the best single piece of evidence in this entire subject, and it is not an anecdote. It is normative specification text.
ECMA-262’s Annex B is headed “Annex B (normative) Additional ECMAScript Features for Web Browsers”. Not informative — normative. Its own opening states: “The ECMAScript language syntax and semantics defined in this annex are required when the ECMAScript host is a web browser. The content of this annex is normative but optional if the ECMAScript host is not a web browser.” And then its preamble states this article’s thesis nearly word for word:
“All of the language features and behaviours specified in this annex have one or more undesirable characteristics and in the absence of legacy usage would be removed from this specification. However, the usage of these features by large numbers of existing web pages means that web browsers must continue to support them.”
The committee has written down, inside the standard, that parts of the standard are bad and survive only because deleting them would hurt users. What is required of every browser in the seventeenth edition, published in 2026, includes String.prototype.blink(), bold(), italics() and strike(); Date.prototype.getYear(), which returns the year minus 1900 and whose own spec note recommends getFullYear instead because it avoids the year 2000 problem; escape and unescape; HTML-like comments inside JavaScript; and String.prototype.trimLeft and trimRight, preserved as aliases after ES2019 standardised the better-named trimStart and trimEnd. Renaming a thing on the web means shipping both names forever.

One level deeper, the standard contains a formal mechanism that lets a single object lie about its own type. Search the spec for [[IsHTMLDDA]] — an internal slot whose holders “behave like undefined in the ToBoolean and IsLooselyEqual abstract operations and when used as an operand for the typeof operator.” Its note is blunt about scope:
“Objects with an [[IsHTMLDDA]] internal slot are never created by this specification. However, the document.all object in web browsers is a host-defined exotic object with this slot that exists for web compatibility purposes.”
Pages written in the 1990s branched on document.all to detect Internet Explorer. If document.all were truthy in a modern browser, those pages would take the IE branch. So the standard specifies an object that exists and reports that it does not — if (document.all) is falsy, typeof document.all is "undefined", and both behaviours are required. There are, the spec adds, no other known examples of this type of object.
The same discipline extends to the document itself. When ==‘s abstract operation was renamed from “Abstract Equality Comparison” to IsLooselyEqual, the editors kept an oldids mapping so the decade-old anchor in somebody’s Stack Overflow answer still resolves. TC39 does not just refuse to break your code; it refuses to break your bookmarks.
The Fix That Was Refused on Principle
typeof null === "object" is the most-mocked line in the language, and its origin is mundane: in the ten-day implementation, values were tagged, the object tag was zero, null was a null pointer, and typeof read the tag. Eich has called it a leaky abstraction, not a design choice.
The folklore then says it cannot be fixed because fixing it would break the web. That is true of the obvious fix and false of the one that was actually on the table, which is what makes this the strongest single instance of the constraint at work. An archived es-discuss thread from 8–9 May 2012 shows Eich describing the live proposal:
Hang on. The proposal is to change typeof null == “null” only under opt-in to Harmony.

Opt-in only. It would have applied inside new, explicitly ES6-targeting code and changed the behaviour of exactly zero already-deployed pages, because nothing deployed had opted in to anything. It was rejected anyway. David Herman, in the same thread, gives the reason, and it is not compatibility:
“Since we can’t eliminate the old typeof semantics, we end up with the language having different semantics in different contexts. And then once we moved to 1JS, it just seemed that much worse to have the variability, since the exact same code can have different meanings right near each other”
“1JS” — One JavaScript — is the committee’s own commitment against any mechanism that lets the same source text mean different things depending on an opt-in flag, whether that flag is a directive, a module boundary or a version pragma. It is a stricter rule than “don’t break deployed pages”: it also forbids new code from forking the language’s semantics. Eich’s own summary, later in the thread: “I think we should consider Object.isObject just because the typeof null change replaced it, but 1JS killed that replacement.”
So typeof null is not an oversight that nobody got around to. It is an acknowledged bug — a community issue on tc39/ecma262 reporting it is open and undisputed — that survives because the available fix violated a design principle the committee valued more than the fix. That is a far more interesting fact than “JavaScript is broken,” and it is the shape of nearly every wart worth studying.
The Words the Specification Does Not Use

One more habit worth stealing before the map. When somebody tells you a document establishes something, grep the document for the word. Applied to the 2.1-million-character ES2026 text, that method produces a set of findings you cannot get any other way (all counted 2026-09-09):
- “Temporal Dead Zone” appears zero times. “TDZ” appears zero times as the term. The single most-taught piece of JavaScript vocabulary is not in the standard. The spec’s own term for the state is an uninitialized binding, and reading one throws a
ReferenceErrorregardless of strictness. - “Hoisting” is not the name of any mechanism in the specification — though here the popular claim that the word is absent is itself too strong, and checking rather than repeating it is the point. The string occurs 35 times in ES2026: 29 are the grammar nonterminal
HoistableDeclaration, and the remaining six are passing prose, only three of which concern declarations at all — a note that “a lexical binding is hoisted and preinitialized prior to evaluation of its initializer”, a reference to “var/let hoisting conflicts”, and a note that a direct eval “will not hoist var declaration over a like-named lexical declaration”. The other two describe a compiler hoisting bounds checks out of loops. No algorithm is named or defined as hoisting. What actually happens isFunctionDeclarationInstantiation, which pre-creates bindings before a function body runs a statement. - “Syntactic sugar” appears zero times, which matters because
classis not sugar: class code is strict-mode only and cannot opt out, a class constructor carries an[[IsClassConstructor]]slot and throws aTypeErrorif called withoutnew, and the class binding sits in the same uninitialised state aslet. Those are semantics afunctioncannot express. - “Harmony” appears zero times. “ES4” appears zero times. “Oracle” appears zero times. “JavaScript” appears exactly once — in a parenthetical crediting originating technologies. The standard names the language a single time and never names the holder of its trademark.
Use the popular vocabulary if it helps you teach. Just know it is teaching vocabulary, and that grepping the actual source of truth will not find it.
Where This Goes Next: The Fourteen Companion Articles
Each of the following owns a layer this article deliberately does not. None of them are published yet, so they appear here as titles rather than links — the map, not the hyperlinks.
On the standard and the name. What ECMAScript Is is the on-ramp: the standard versus the implementations, and the fourth naming step in full. JavaScript vs ECMAScript answers the high-volume version of that question with a checkable fact — the specification names “JavaScript” exactly once. The ECMAScript 4 Collapse tells the governance story entirely from Ecma’s own document archive, naming positions rather than villains. Who Invented JavaScript works from the HOPL paper rather than blog posts, and does not debunk a claim that is true.
On the engine. JavaScript JIT Compilation takes the bet apart properly — speculation, tiering, inline caches, hidden classes — and prices it honestly. How V8 Runs JavaScript treats V8 as a real C++ project with two very different compiler funerals in its history. JavaScript Deoptimization is about the cliff: what breaks a hidden class, what makes a call site megamorphic, and why a deopt loop is the pathological case. Why JavaScript Benchmarks Mislead is a measurement article whose subject is misattributed measurements. The V8 Sandbox and JIT Security is defensive-only, and turns on a denominator most write-ups drop: of Chrome exploits caught in the wild in 2021–2023, V8’s team reports 60% were V8 vulnerabilities — of in-the-wild renderer memory-corruption exploits, not of Chrome bugs in general — and that these are JIT logic errors a memory-safe language would not fix.
On the language and the platform. typeof null in JavaScript expands the refused fix above into the hub’s cleanest case study. CommonJS vs ESM covers the most practically painful thing in the language today: require() of an ES module only became non-experimental in Node v25.4.0, and categorically excludes any module using top-level await. What Node.js Actually Added argues that Node did not make JavaScript fast — V8 did — and that Node made it ambient, then complicates its own claim with LiveWire. Deno vs Bun vs Node treats a runtime as an argument rather than a feature matrix, and its honest finding cuts against both challengers: npm compatibility beat design purity. Disclosure for that piece and this one: Bun was acquired by Anthropic on 2 December 2025, and Anthropic describes Bun as the infrastructure powering Claude Code — the tool these articles were drafted with. Vendor benchmarks from any of the three are marketing until independently verified. Finally, A JavaScript Reading Ladder leads with the free primary material, because here it genuinely beats the books.
What Transfers to Any Interface You Cannot Take Back
Strip out the JavaScript and a general problem is left: what do you do when you have made a mistake in something that billions of running instances already depend on, and neither of the two standard tools — remove the bad option, or force a version bump — is available to you?

JavaScript’s answer, visible in its own normative text, is a third category: a scoped, named, documented carve-out, with the reason stated in the specification itself. Annex B is that. [[IsHTMLDDA]] is that, scoped as narrowly as a thing can be. The oldids anchor mapping is the same instinct applied to the document. A documented wart is an asset; an undocumented one is a landmine, and the difference costs nothing but the discipline of writing it down. Three more transfer directly.
A release that is an event becomes a hostage; a release that is a train cannot be. When scope is negotiable, blocking the release is the strongest move available to anyone who dislikes its contents — and ES4 died of exactly that. Fix the date and let scope float.
Design for partial retreat. ES4 was one monolithic edition, so disagreement about namespaces was necessarily disagreement about everything shipping alongside them. TC39’s answer is per-proposal staging with regression and withdrawal as defined transitions and no concept of rejection at all. A design with no defined retreat has two outcomes, and one of them is a four-year stalemate.
Gate on demonstrated interoperability, not on design approval. Two implementations passing a shared conformance suite is a cheaper and more honest bar than any amount of committee confidence.
And one caution earned the hard way in researching this: a participant’s account is not the institution’s position, a dated snapshot is silent about everything after its date, and a count is not evidence until you have looked at what it matched. The phrase “deemed unsound for the Web” is Eich’s, absent from both Ecma documents. tc39.es/ecma262/ will tell you about 2027 when you asked about 2026. And the widely repeated claim that “hoisting” appears nowhere in the specification does not survive printing the matches. Verifying against the wrong document, or against a number nobody looked at, produces a confident wrong answer — which is worse than an unverified one, because it looks checked.
❓ Frequently Asked Questions
Did Brendan Eich really write JavaScript in ten days? He wrote the prototype in ten days, and the sentence is his own, from his blog on 21 June 2011 — there is nothing to debunk. What those ten days produced, by his own account, was a bytecode compiler and interpreter, in early-to-mid-May 1995, embedded in a pre-alpha Navigator. The rest of 1995 was browser integration, an August 1995 feature freeze determined what actually shipped, and the ten-day source tree was itself rewritten into SpiderMonkey in late 1996.
Why is there no ECMAScript 4? Because two camps deadlocked over what a fourth edition should be, not over whether to have one — Microsoft’s own November 2007 position paper opens its case with “The web needs a 4th Edition of the ECMAScript Specification”. Ecma has no mechanism for minor releases, so the next edition number was a single indivisible prize. The fight ended in July 2008; what shipped in December 2009 was announced as “ES3.1” and published as the fifth edition. Ecma’s archive still lists the fourth as “(not existing).”
What is the difference between JavaScript and ECMAScript? ECMAScript is the standard, ECMA-262, maintained by TC39 and published each June. JavaScript is the name everyone uses for the thing implementations run — and it is a trademark the committee does not own, which is why the specification names the language exactly once and never names the trademark holder. What you can actually write is the intersection of the standard and what browsers do, and Annex B exists because those two are not identical.
Is typeof null === "object" ever going to be fixed? Almost certainly not, and the reason is more specific than “it would break the web.” An opt-in-only fix that would have changed the behaviour of zero deployed pages was on the table in 2010–2012 and was rejected under the committee’s “1JS” principle, which forbids the same source text meaning different things in different lexical contexts. The bug is acknowledged, not disputed; what is settled is that the available fix cost more than the bug.
How many compilers does V8 use, and why not just one? Four tiers as of 2026 — a bytecode interpreter, a fast baseline compiler, a mid-tier optimiser and a top-tier optimiser — because most functions run a handful of times, a few run millions, and you cannot tell which is which in advance. V8’s own explanation of the ceiling is that with two compilers you can only tier up faster by removing optimisation passes, which costs peak performance. The price of the arrangement is memory, warm-up and unpredictability.
How do I check whether a feature is actually in ECMAScript 2026? Use the dated snapshot at tc39.es/ecma262/2026/, not the undated tc39.es/ecma262/. The undated URL is the living draft — as of 9 September 2026 it is titled ECMAScript® 2027 Language Specification. Explicit resource management (using) is a live example: 149 occurrences of its grammar symbol in the draft, zero in the published 2026 edition, with an expected publication year of 2027 on TC39’s own tracker.
📦 Recommended Resources
Some links below are Amazon affiliate links; buying through them supports this site at no extra cost to you.
Start with the free primary material, because on this subject it genuinely beats the books. Wirfs-Brock and Eich’s JavaScript: The First 20 Years is 189 peer-reviewed pages, co-authored by the person who wrote the language, and free — it is the single best-value document here and nothing in print supersedes it. The dated ECMAScript 2026 specification is the actual source of truth for what shipped, and grepping it is a skill worth twenty minutes. Ecma’s document archive preserves the ES4 dispute as signed, dated papers rather than folklore. And V8’s blog is where the engine team explains its own decisions, including the two it later reversed. The three books below are for the layer underneath — the reasoning that makes those documents legible.
- Crafting Interpreters by Robert Nystrom — the most directly relevant book on this list, and it is not obvious why until you read the section above about what the ten days actually produced. Nystrom builds two implementations of the same language: a tree-walking interpreter, then a bytecode compiler and virtual machine. Working through the second one is the fastest way to understand why “bytecode compiler and interpreter from the start” is a substantive architectural claim rather than a detail, and why a bytecode representation is what a language needs when it has to run somewhere other than where it was designed to run.
- JavaScript: The Definitive Guide (7th ed.) by David Flanagan — the reference to keep within reach while reading the specification, not a substitute for it. Its value here is calibration: when the spec’s algorithm for
typeofor an environment record’sGetBindingValueis technically complete and humanly opaque, Flanagan tells you what the behaviour is for, which makes the normative text tractable. Read it alongside the spec rather than instead of it, and note the publication date on any edition you buy — the annual cadence means a language reference has a shelf life now.
- Eloquent JavaScript (4th ed., 2024) by Marijn Haverbeke — worth naming precisely because it is free to read online in full, Creative Commons licensed, which is entirely in keeping with the rest of this list. Its treatment of functions, closures and the object model is the clearest short account of the parts of the language that, as the article argues, were the one thing that did not need thirty years of committee work to become good.
✅ Pro tip: before any of these, spend twenty minutes with the specification itself and one search box. Open the dated 2026 snapshot, search it for “Temporal Dead Zone”, then for “syntactic sugar”, then for “Oracle” — and watch three pieces of received JavaScript wisdom return zero hits each. Grepping the source of truth for a word you were told is in it is the cheapest research technique in this business, and it is how most of the findings in this article were located.