<p dir="auto">EDIT: PR at <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="339601340" data-permission-text="Title is private" data-url="https://github.com/babel/babel/issues/8293" data-hovercard-type="pull_request" data-hovercard-url="/babel/babel/pull/8293/hovercard" href="https://github.com/babel/babel/pull/8293">#8293</a></p>
<p dir="auto">Stage-0 Readme: <a href="https://github.com/babel/babel/blob/48fe688a10d83486defdda223ac8d8d88057975d/packages/babel-preset-stage-0/README.md#babelpreset-stage-0">https://github.com/babel/babel/blob/48fe688a10d83486defdda223ac8d8d88057975d/packages/babel-preset-stage-0/README.md#babelpreset-stage-0</a></p>
<p dir="auto">Can migrate automatically now with <a href="https://github.com/babel/babel-upgrade">https://github.com/babel/babel-upgrade</a> (<code class="notranslate">npx babel-upgrade</code>) as of <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="343918162" data-permission-text="Title is private" data-url="https://github.com/babel/babel-upgrade/issues/69" data-hovercard-type="pull_request" data-hovercard-url="/babel/babel-upgrade/pull/69/hovercard" href="https://github.com/babel/babel-upgrade/pull/69">babel/babel-upgrade#69</a></p>
<hr>
<p dir="auto">I think there's a reasonable argument to be made for stage 3 features being easily toggle-able, and by that point they are less likely to have major breaking changes, so I'm not as against it. We've had occasional conversations, but I think we should decide.</p>
<p dir="auto">The stage &lt; 3 presets are likely to change over time, making versioning difficult for them, and the community has grown to overactively enable stage-0 which I see as a dangerous precedent. To me it seems like we should remove these presets and instead use documentation to encourage people to enable experimental plugins on a case-by-case basis for the ones they <em>actually</em> want, rather than just enabling everything for the sake of it.</p>
<p dir="auto">I just want to make sure we have this conversation while we have the easy opportunity of dropping them before <code class="notranslate">7.x</code>.</p>
<p dir="auto">So there's a problem with how stage-x plugins are designed right now. They are versioned in lockstep with the rest of Babel. However these stage-x features change throughout the process and may make breaking changes at any time.</p>
<p dir="auto">Babel's lockstep versioning causes a weird tradeoff of either following SemVer or keeping up with the spec. At the same time Lockstep versioning is important for the ecosystem.</p>
<p dir="auto">I've talked to contributors privately about this and figured I'd create an issue:</p>
<p dir="auto">I want to get rid of the <code class="notranslate">babel-preset-stage-x</code> plugins and move all of the stage-x plugins into their own monorepo with independent (see Lerna) versioning.</p>
<p dir="auto">This way there are no more presets for stages and people have to manually enable plugins by individual features. These plugins can then make major version bumps at any time.</p>
<p dir="auto">The plugins should be named <code class="notranslate">babel-plugin-transform-proposal-{feature}</code>, when they are accepted by TC39 they move into the main repository and are named <code class="notranslate">babel-plugin-transform-es{year}-{feature}</code> and included in the relevant presets.</p>
<p dir="auto">The one problem that needs to be solved is parsing. We need to be able to change the syntax of a proposal at any time so that we can track changes like decorators moving from <code class="notranslate">@</code> to <code class="notranslate">#</code> (which was turned down by the committee but we need a better way in Babel to handle that type of scenario).</p>
<p dir="auto">Babylon has the ability to write syntax features as plugins (see <a href="https://github.com/babel/babylon/tree/master/src/plugins">https://github.com/babel/babylon/tree/master/src/plugins</a>), but right now es proposals are embedded within the parser. Instead we should build es proposal syntax as plugins.</p>
<p dir="auto">Right now Babylon does not allow external plugins to be added in order to prevent the ecosystem from going mad with power using them.</p>
<p dir="auto">I would like to suggest adding a whitelist to Babylon for allowed parser plugins in Babylon and allowing them to be included in Babel plugins like:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="export default function babelPlugin() {
  return {
    __internal_only_dont_use_this_or_we_will__find_you_and_intentionally_break_your_plugin_in_a_patch_release__you_have_been_warned__: {
      __dangerous_dont_use__: {
        __seriously_no__: {
          __just_fork_babylon_yourself__: {
            parserPlugin: { name: 'proposal-{feature}', version: require('./package.json').version, babelVersions: '^6.0.0', plugin: require('./parser-plugin') }
          }
        }
      }
    }
  };
}"><pre class="notranslate"><span class="pl-k">export</span> <span class="pl-k">default</span> <span class="pl-k">function</span> <span class="pl-en">babelPlugin</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-k">return</span> <span class="pl-kos">{</span>
    <span class="pl-c1">__internal_only_dont_use_this_or_we_will__find_you_and_intentionally_break_your_plugin_in_a_patch_release__you_have_been_warned__</span>: <span class="pl-kos">{</span>
      <span class="pl-c1">__dangerous_dont_use__</span>: <span class="pl-kos">{</span>
        <span class="pl-c1">__seriously_no__</span>: <span class="pl-kos">{</span>
          <span class="pl-c1">__just_fork_babylon_yourself__</span>: <span class="pl-kos">{</span>
            <span class="pl-c1">parserPlugin</span>: <span class="pl-kos">{</span> <span class="pl-c1">name</span>: <span class="pl-s">'proposal-{feature}'</span><span class="pl-kos">,</span> <span class="pl-c1">version</span>: <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">'./package.json'</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">version</span><span class="pl-kos">,</span> <span class="pl-c1">babelVersions</span>: <span class="pl-s">'^6.0.0'</span><span class="pl-kos">,</span> <span class="pl-c1">plugin</span>: <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">'./parser-plugin'</span><span class="pl-kos">)</span> <span class="pl-kos">}</span>
          <span class="pl-kos">}</span>
        <span class="pl-kos">}</span>
      <span class="pl-kos">}</span>
    <span class="pl-kos">}</span>
  <span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">I think that should be enough.</p>
<p dir="auto">It's gonna be controversial to remove the stage presets, but it is the right thing to do for the ecosystem in my opinion.</p>