Asher Cohen
Back to posts

Future JavaScript Proposals: What's Coming Next

Overview of upcoming JavaScript features — pipeline operator, pattern matching, records & tuples, and the TC39 proposal process

Introduction

JavaScript evolves through the TC39 process, with new features progressing through stages from proposal to official specification. Understanding what's coming helps you write forward-looking code and adopt new features confidently.

The TC39 Process

Features progress through 4 stages:

StageNameDescription
0StrawmanInitial idea
1ProposalFormal proposal, champion assigned
2DraftSpecification text, initial implementation
3CandidateReady for implementations, gathering feedback
4FinishedReady for inclusion in the spec

Pipeline Operator (|>)

The pipeline operator makes function composition readable by flowing a value through a series of functions:

// ❌ Without pipeline — nested calls, hard to read
const result = capitalize(doubleSay(greeting(exclaim('hello'))));

// ❌ Without pipeline — intermediate variables
const exclaimed = exclaim('hello');
const greeted = greeting(exclaimed);
const doubled = doubleSay(greeted);
const result = capitalize(doubled);

// ✅ With pipeline operator (Stage 2)
const result = 'hello'
  |> exclaim(%)
  |> greeting(%)
  |> doubleSay(%)
  |> capitalize(%);

// With arrow functions
const result = 'hello'
  |> exclaim
  |> greeting
  |> doubleSay
  |> capitalize;

Status: Stage 2 — actively being refined.

Pattern Matching

Bringing powerful pattern matching from functional languages to JavaScript:

// ❌ Without pattern matching — verbose conditionals
function getDescription(value) {
  if (Array.isArray(value)) {
    return `Array with ${value.length} items`;
  } else if (value === null) {
    return 'Null value';
  } else if (typeof value === 'object') {
    return `Object with keys: ${Object.keys(value).join(', ')}`;
  } else {
    return `Value: ${value}`;
  }
}

// ✅ With pattern matching (Stage 1)
function getDescription(value) {
  return match (value) {
    when ([]): 'Empty array';
    when ([first, ...rest]): `Array starting with ${first}`;
    when (null): 'Null value';
    when ({ name, age }): `${name}, ${age} years old`;
    default: `Value: ${value}`;
  };
}

Status: Stage 1 — proposal under development.

Records and Tuples

Immutable data structures with value-based equality:

// Records (immutable objects)
const user = #{ name: 'Alice', age: 30 };
// user.name = 'Bob'; // TypeError — immutable!

// Value equality
const user1 = #{ name: 'Alice', age: 30 };
const user2 = #{ name: 'Alice', age: 30 };
console.log(user1 === user2); // true! (value equality)

// Tuples (immutable arrays)
const point = #[1, 2, 3];
// point[0] = 5; // TypeError — immutable!

const point1 = #[1, 2, 3];
const point2 = #[1, 2, 3];
console.log(point1 === point2); // true! (value equality)

// Nested
const data = #{
  users: #[
    #{ name: 'Alice', scores: #[95, 87, 92] },
    #{ name: 'Bob', scores: #[78, 85, 90] }
  ]
};

Status: Stage 2 — actively being refined.

Temporal (Better Dates)

A modern replacement for the problematic Date object:

// Current Date API problems
const date = new Date(2024, 0, 1); // Month is 0-indexed!
date.getMonth(); // 0 (January) — confusing

// Temporal (Stage 3)
import { Temporal } from '@js-temporal/polyfill';

// Clear, immutable API
const date = Temporal.PlainDate.from({ year: 2024, month: 1, day: 1 });
console.log(date.month); // 1 (January — 1-indexed!)

// Date arithmetic
const nextWeek = date.add({ days: 7 });
const lastMonth = date.subtract({ months: 1 });

// Duration between dates
const start = Temporal.PlainDate.from('2024-01-01');
const end = Temporal.PlainDate.from('2024-12-31');
const duration = start.until(end);
console.log(duration.days); // 365

// Time zones
const zonedDateTime = Temporal.ZonedDateTime.from({
  year: 2024,
  month: 1,
  day: 1,
  hour: 12,
  timeZone: 'America/New_York'
});

Status: Stage 3 — polyfill available, nearing completion.

Decorators

A clean syntax for modifying classes and their members:

// Decorators (Stage 3)
function logged(target, context) {
  const original = target;
  return function(...args) {
    console.log(`Calling ${String(context.name)} with`, args);
    return original.apply(this, args);
  };
}

class MyClass {
  @logged
  myMethod(arg) {
    return `Result: ${arg}`;
  }
}

// Usage
const instance = new MyClass();
instance.myMethod('test');
// Logs: "Calling myMethod with ['test']"
// Returns: "Result: test"

Status: Stage 3 — implementations in progress.

JavaScript as a Compilation Target

JavaScript's role as the universal target language for other languages:

  • TypeScript → JavaScript (most popular)
  • Reason/ReScript → JavaScript (OCaml-like)
  • Elm → JavaScript (pure functional)
  • ClojureScript → JavaScript (Lisp dialect)
  • Kotlin/JS → JavaScript (from JVM ecosystem)
  • Dart → JavaScript (via dart2js)
  • Rust → WebAssembly + JavaScript glue

This ecosystem means JavaScript isn't just a language — it's a platform.

Already Landed Features

Recent additions worth mastering:

// Optional chaining (ES2020)
const city = user?.address?.city;

// Nullish coalescing (ES2020)
const name = input ?? 'Default';

// Logical assignment (ES2021)
x ??= defaultX;
x ||= fallbackX;
x &&= conditionX;

// Numeric separators (ES2021)
const billion = 1_000_000_000;

// Top-level await (ES2022)
await fetchData(); // Works at module top level

// Array findLast / findLastIndex (ES2023)
const last = array.findLast(x => x > 10);

// Immutable array methods (ES2023)
const sorted = array.toSorted();
const reversed = array.toReversed();
const spliced = array.toSpliced(1, 2);

How to Stay Current

  • Follow TC39github.com/tc39/proposals
  • Use polyfills — Try features before they land
  • Read the spectc39.es/ecma262
  • Configure Babel/TypeScript — Enable stage 3+ proposals
  • Test in canary builds — Chrome Canary, Firefox Nightly

Conclusion

JavaScript's future is exciting:

  • Pipeline operator — Clean function composition
  • Pattern matching — Expressive conditional logic
  • Records & Tuples — True immutability
  • Temporal — Finally, a good date API
  • Decorators — Elegant metaprogramming

The language continues to evolve while maintaining backward compatibility. Stay informed, experiment with proposals, and adopt features as they stabilize.

#javascript #tc39 #future #proposals #esnext #web-development