The TC39 Process document defines what steps a proposal must take. This document is the source of the various stages that each feature goes through, which you may know best from the various stage-X presets from Babel. These stages are called the “maturity stages.” The table defining the stages is a quick read that will give you a ton of context for how much has gone into a given proposal.
What does it mean to be “stage 1” though? If there’s a Babel plugin for it, why shouldn’t we use a feature? To answer that, let’s walk through what the different stages mean.
TC39 maturity stages
Brand new proposals are referred to as “strawman” or “stage 0” proposals. Stage 0 has very little significance. It means that somebody has formally proposed an idea to the committee — that’s it. The process document notes that this stage has no restrictions and does not require an attempt at specifying behavior. TC39 maintains a list of stage 0 proposals, some of which have not progressed towards standardization in 4 years, and several of which have been formally dropped.
Relying on stage 0 features in production apps is a gamble in the long run. So why have developers downloaded the stage 0 Babel preset 740,000 times (at time of writing) in the past week?
Are you using it? …should you be?
These stages live in the readme of the TC39 proposals repo. These are the features actively working their way through the process.
Stages 1 and 2 require an attempt to specify the behavior of the proposed feature, but implementations are intended to be exploratory. The more complex the proposal, the more likely it is to change as it moves from stage 1 to 2 to 3. If you rely on a proposal whose behavior changes, you may be stuck with a significant rewrite if you ever want to update your build tools.
That’s not to say that stage 3 proposals are guaranteed to advance. Features at earlier stages are less likely to enter the spec because of how much work it takes to completely specify the behavior and implement it in browsers. Features at stage 3 may be rejected because irreconcilable issues are discovered while implementing, or in the case of
Object.observe, because the feature was deemed unnecessary.
Proposals that are considered complete and ready for formal inclusion in the spec advance to stage 4. These move to the finished proposals section of the TC39 proposals repo. A large amount of work is required to advance from stage 3 to 4. There must be acceptance tests and must be implemented in 2 independent VMs.
Ecma International and ECMAScript
- 1999, ES3
- 2009, ES5, originally ES3.1
- 2015, ES2015, with annual releases ever since.
ES6, ES2015, or ES Harmony
Following ES5, ES2015 was the first release under a newly developed process, led by TC39 (Technical Committee 39 of Ecma). It was the first release after the various factions reconciled and began working together again, hence the codename “Harmony.”
Because this new process has been working so smoothly, recent releases of ECMAScript have not been the significant overhauls that ES2015 were. Dr. Axel Rauschmayer’s blog has excellent summaries of the new features introduced in each 2016 2017, and 2018.
These official releases have become less important. Babel enables us to use features months or years before they’re officially released, and we may not use the native implementations for years afterward due to legacy browsers. Babel has moved to make it even easier for us to forget about this process with
babel-preset-env. By configuring it with what browsers you need to support, it will provide minimal transpilation and polyfills to use native implementations whenever possible.
Babel has also moved to deprecate the
stage-x presets for reasons given in a blog post announcing the change.
babel-preset-env provides a much more developer-centric solution to the same problem, and is recommended instead of manually setting presets.