Frontend Development 21 min read

What ECMAScript Proposals Will Shape JavaScript’s Future?

This article surveys the most interesting ECMAScript proposals—ranging from new data structures like Record & Tuple to syntax enhancements such as the pipeline operator—explaining their purpose, current stage, and practical examples, while also covering the TC39 process and related background for front‑end developers.

Taobao Frontend Technology
Taobao Frontend Technology
Taobao Frontend Technology
What ECMAScript Proposals Will Shape JavaScript’s Future?

Preface

Recently, several intriguing ECMAScript proposals have emerged, such as Record & Tuple data types, Observable inspired by RxJS, throw Expressions for better error handling, and Error Cause. These proposals promise a new wave of JavaScript evolution. This article lists a selection of proposals worth watching, including new APIs like

replaceAll

and new syntax such as

?.

and

??

, most of which are still in stage 1 or 2 and therefore require Babel plugins or await further standardisation.

The background information below is largely sourced from Snowy’s “JavaScript 20 Years – Creating Standards” lecture.

ECMA (European Computer Manufacturers Association) maintains computer‑related standards. JavaScript originated at Netscape, which turned to ECMA to avoid Microsoft’s dominance.

In 1996 JavaScript entered the ECMA family and became ECMAScript (ES). TC39 is the technical committee that steers ES development, composed of representatives from major browser vendors.

ECMA‑262 is the official specification, now in its 11th edition (June 2020). ES6 (2015) is the most widely known release, and the latest drafts (e.g., ES2022) are publicly available.

Other ECMA standards include ECMA‑414 (ES module suite), ECMA‑404 (JSON syntax), and even standards for DVD formats.

TC39 proposals progress through five stages: strawman (stage 0), proposal (stage 1), draft (stage 2), candidate (stage 3), and finished (stage 4). Only finished proposals become part of the annual ES release.

For more details, see “The TC39 process for ECMAScript features”.

Record & Tuple (stage 2)

The

proposal-record-tuple

adds two immutable data structures: Record (object‑like) and Tuple (array‑like). Their members can only be primitive values, making them compared by value (e.g.,

===

returns

true

when contents match).

<code>const proposal = #{
  id: 1234,
  title: "Record & Tuple proposal",
  contents: `...`,
  keywords: #["ecma", "tc39", "proposal", "record", "tuple"]
};

const measures = #[42, 12, 67, "measure error: foo happened"];</code>

.at() – Relative Indexing Method (stage 3)

The

proposal-relative-indexing-method

introduces

at()

for indexable objects (Array, String, TypedArray). It enables negative indexing, simplifying access to the last element without manual length calculations.

<code>// Traditional ways
arr[arr.length - 1]; // or arr.slice(-1)[0];

// With at()
arr.at(-1); // returns the last element</code>

Related proposals include

proposal-array-last

(stage 1) and

proposal-array-find-from-last

.

Temporal (stage 3)

The

proposal-temporal

provides a standardized date‑time API under a global

Temporal

namespace, offering modern alternatives to the legacy

Date

object.

Temporal.Instant.from('1969-07-20T20:17Z')

creates a fixed‑point instant.

Temporal.PlainDate.from({year: 2006, month: 8, day: 24})

yields a calendar date.

Temporal.PlainTime.from({hour:19, minute:39, second:9, millisecond:68, microsecond:346, nanosecond:205})

creates a wall‑clock time.

Temporal.Duration.from({hours:130, minutes:20})

represents a time span.

Private Methods (stage 3)

The

private-methods

proposal adds true private fields, methods, and accessors to JavaScript classes using the

#

syntax, distinct from TypeScript’s

private

keyword.

<code>class IncreasingCounter {
  #count = 0;
  get value() {
    console.log('Getting the current value!');
    return this.#count;
  }
  increment() {
    this.#count++;
  }
}</code>

It also introduces static class fields via

proposal-class-fields

, allowing syntax such as

static x = 8;

without transpilation.

Top‑level await (stage 4)

The

proposal-top-level-await

removes the need for an enclosing async function, permitting

await

at the module’s top level (supported in Node 14.8+).

Import Assertions (stage 3)

The

proposal-import-assertions

adds syntax to assert module types during import, e.g.:

<code>import json from "./foo.json" assert { type: "json" };</code>
Note: Import‑assertions were later split into a separate proposal-json-modules proposal.

Error Cause (stage 3)

The

proposal-error-cause

enables passing an underlying error as the

cause

property of a new

Error

, simplifying error propagation across async call stacks.

<code>async function doJob() {
  const raw = await fetch('//domain/resource-a').catch(err => {
    throw new Error('Download raw resource failed', { cause: err });
  });
  const result = doComputationalHeavyJob(raw);
  await fetch('//domain/upload', { method: 'POST', body: result }).catch(err => {
    throw new Error('Upload job result failed', { cause: err });
  });
}</code>

Decorators (stage 2)

The

proposal-decorators

brings native decorator syntax to JavaScript, distinct from the TypeScript implementation. Frameworks like Angular, NestJS, and MidwayJS already rely heavily on decorators.

Decorator illustration
Decorator illustration

Do Expression (stage 1)

The

proposal-do-expressions

introduces expression‑oriented syntax, allowing blocks that evaluate to a value:

<code>let x = do { let tmp = f(); tmp * tmp + 1 };
let y = do { if (foo()) { f() } else if (bar()) { g() } else { h() } };</code>

Pipeline Operator (stage 1)

Currently the most starred proposal.

The

proposal-pipeline-operator

adds the

|&gt;

operator to improve readability of function composition.

<code>let result = "hello" |&gt; doubleSay |&gt; capitalize |&gt; exclaim; // "Hello, hello!"</code>

Partial Application Syntax (stage 1)

The

proposal-partial-application

offers a concise way to fix some arguments of a function using

?

placeholders.

<code>const addOne = add(1, ?);
addOne(2); // 3
const addTen = add(?, 10);
addTen(2); // 12</code>

await.opts (stage 1)

The

proposal-await.opts

adds

await.all

,

await.race

,

await.allSettled

, and

await.any

as syntactic sugar for the corresponding

Promise

methods.

<code>// before
await Promise.all(users.map(async x => fetchProfile(x.id)));
// after
await.all users.map(async x => fetchProfile(x.id));</code>

These proposals represent only a subset of the many interesting ideas currently progressing through TC39’s stages. For a complete list, visit the TC39 Proposals Tracking page.

frontendJavaScriptECMAScriptlanguage featuresJavaScript proposalsTC39
Taobao Frontend Technology
Written by

Taobao Frontend Technology

The frontend landscape is constantly evolving, with rapid innovations across familiar languages. Like us, your understanding of the frontend is continually refreshed. Join us on Taobao, a vibrant, all‑encompassing platform, to uncover limitless potential.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.