Skip to main content

7.6.0 Released: Private static accessors and V8 intrinsic syntax

· 4 min read

We just released a new minor Babel version!

It includes support for static private accessors in classes, and parser support for the V8 intrinsics syntax. We also fixed a bunch of long-standing issues related to TDZ handling, and improved support for do-expressions. You can read the whole changelog on GitHub.

Thanks to Serhii Muryhin, Ashwin Ramaswami, Sungmin Lee, Serge Havas, Ziad El Khoury Hanna, Even Alander, Shrey Banga, Dylan Kirkby, Ajay Sagar, Adam Ramberg, and Bin Xin for their first PRs! (And also thanks to Codetriage README Bot and dependabot 🤖)

Bloomberg is continuing to sponsor the implementation of new class features in Babel: after giving us a lot of new class features (static private fields, private instance methods, private instance accessors, and static private methods), they've just implemented static private getters and setters.

Another big shout out goes to Frontend Masters for making two big donations this past month, as well as all our other sponsors who allow the Babel team to spend more time on the project!

If you or your company want to support Babel and the evolution of JavaScript, but aren't sure how, you can donate to us on OpenCollective and, better yet, work with us on the implementation of new ECMAScript proposals directly! As a volunteer-driven project, we rely on the community's support to both fund our efforts in supporting the wide range of JavaScript users and taking ownership of the code. Reach out to Henry at if you'd like to talk more!

Private static accessors (getters and setters) (#10217)

class Resource {
static #loaderInstance = null;

static get #loader() {
if (!this.#loaderInstance) this.#loaderInstance = new Loader();
return this.#loaderInstance;

status = null;

constructor(url) {
this.status = Resource.#loader.load(url);

Thanks to Tim (Bloomberg) for implementing this proposal!

You can test this new feature by adding @babel/plugin-proposal-private-methods to your config, if you haven't already added it, or by enabling the stage-3 preset in the online repl.

Class private features support is finally complete 🎉

Class PrivateInstanceStatic
class A { #a = 1 }
class A { #a() {} }
class A { get #a() {} }

It's time to party!

V8 intrinsic runtime functions parsing (#10148)

⚠️ This is a non-standard extension to the language, which can only be used in V8 when enabling the --allow-natives-syntax command-line flag.

V8, the JavaScript engine used by Node.js and Chromium-based browsers, can expose various pieces of internal functionality as JavaScript functions. Although these APIs must not be used in production JavaScript code, these special functions can be useful in testing and debugging scenarios — for example, to understand how your JavaScript values are represented in memory, or to call some ECMAScript specification routines directly.

These so-called “V8 intrinsics” have a different syntax than normal functions: their name always starts with %. Also, they can only be directly called and never used as normal values (you can't, for example, assign them to another variable).

function fn() { /* ... */ }

const status = %GetOptimizationStatus(fn);

if (status === 2) {
console.log("The function is not optimized!");

You can find the whole list of existing V8 intrinsics in V8's source code.

You can enable this syntax in @babel/parser by using the v8intrinsic plugin:

const { parse } = require("@babel/parser");

parse(code, {
plugins: ["v8intrinsic"]

Nullish coalescing operator (??) updates (#10269)

The nullish coalescing stage 3 proposal recently got some updates: to avoid confusion over precedence with other logical operators (&& and ||), the spec has been changed to disallow mixing them.

This means that the following expressions are now invalid:

a ?? b || c;
a && b ?? c;

Instead, you should add parentheses where appropriate:

(a ?? b) || c; /* or */ a ?? (b || c);
(a && b) ?? c; /* or */ a && (b ?? c);

This is similar to how unary minus (-) and the exponentiation operator (**) interact: you can't write -1 ** 2, but you have to choose between (-1) ** 2 and -(1 ** 2).