Skip to main content

7.15.0 Released: Hack-style pipelines, TypeScript const enums and Rhino target support

ยท 4 min read

This release enables parsing top-level await (Stage 4 at the May meeting) and transforming ergonomic brand checks for private fields (Stage 4 at the July meeting) by default. There is also now support for the Hack-style pipeline operator. We also improved our TypeScript support, implementing transform support for const enums and namespace aliases, and we expanded our heuristics to add .displayName to React components created by React.createContext() (#13501).

We also introduced a new compiler assumption, noIncompleteNsImportDetection, to produce a smaller output when compiling ECMAScript modules to CommonJS without worrying about partially initialized namespace imports caused by module cycles.

Additionally, you can now specify Rhino as a compilation target.

You can read the whole changelog on GitHub.

We're really grateful for all the support the community has shown over the last months, since our funding post update in May. Reach out at if you'd like to discuss about sponsorships!


ECMAScript features enabled by defaultโ€‹

In the last two meetings, the top-level await and ergonomic brand checks for private fields proposals reached Stage 4.

import * as db from "database";

await db.connect(); // top-level await

class DBConnector {
static isConnector(obj) {
return #password in obj; // ergonomic brand checks

Babel now supports them by default, so you can remove the following plugins from your configuration:

  • @babel/plugin-syntax-top-level-await
  • @babel/plugin-syntax-private-property-in-object
  • @babel/plugin-proposal-private-property-in-object

Please note that Babel can currently only parse top-level await and cannot transform it.

New TypeScript features (#13324, #13528)โ€‹

TypeScript 4.4 doesn't include any new syntax that we had to implement, other than a minor restriction: you cannot specify the value of an abstract class field.

abstract class C {
abstract prop = 1; // now a SyntaxError!

However, we did add two TypeScript features that we have been missing for a long time: const enums and namespace aliases (import Alias = Namespace).

Previously we presented an error when using const enums since it requires type information to compile correctly. As a workaround, the community built plugins such as babel-plugin-const-enum. Babel now ignores the const modifier when compiling enums, which matches TypeScript's behavior when using the --isolatedModules option.

If you want a more optimized output similar to the default code produced by TypeScript, you can enable the optimizeConstEnums option of @babel/plugin-tranform-typescript or @babel/preset-typescript.

// Input
const enum Animals { Dog }

// Output (default)
var Animals;
(function (Animals) {
Animals[Animals["Dog"] = 0] = "Dog";
})(Animals || (Animals = {}));


// Output with `optimizeConstEnums`

Hack-style pipeline operator support (#13191, #13416)โ€‹

"Hack-style pipelines" is a new flavor of the pipeline operator proposal, intended to replace the "smart mix" variant.

Hack-style pipelines require you to always use a "topic token" (such as #) to reference the value of the previous pipeline step:

// Input
|> `Hello, ${#}!`
|> alert(#);

// output
var _ref, _ref2;

_ref2 = (_ref = "World", `Hello, ${_ref}!`), alert(_ref2);

You can test this proposal by enabling the proposal: "hack" option in @babel/plugin-proposal-pipeline-operator. You must also choose which topic token to use, between "#" and "%":

"plugins": [
["@babel/plugin-proposal-pipeline-operator", {
"proposal": "hack",
"topicToken": "#"

Preparing @babel/eslint-parser for Babel 8 (#13398)โ€‹

We have been slowly continuing to work on Babel 8 in the past months. We are not ready for a Babel 8 beta release yet, but we are starting to expose the first experimental changes.

We plan to fully convert Babel from CommonJS to ECMAScript modules, but this has a problem: configuration loading will be asynchronous more often, and @babel/eslint-parser can only work synchronously (because ESLint only supports synchronous parsers).

@babel/eslint-parser 7.15.0 exposes a new entry-point: @babel/eslint-parser/experimental-worker. It moves the Babel config loading and parsing task to a separate worker which is managed synchronously from the main thread, while still supporting async configuration loading. As an immediate advantage for Babel 7, it allows using native ECMAScript modules for Babel configuration files even when using @babel/eslint-parser.

You can help us by testing it now in your existing projects, and reporting any bug on our issues page:

// .eslintrc.js
module.exports = {
parser: "@babel/eslint-parser/experimental-worker"

This entry-point requires Node.js >= 12.3.0