A proposal is not a shipping contract
Before adopting syntax, answer three questions: has it been standardized, does the build tool understand it, and does the deployed runtime support it? A calendar label such as ES17 cannot answer all three.
The previous version mixed proposals with completed features, included unsupported pattern-matching syntax, and overstated browser availability. This revision keeps the useful grouping, promise, and iterator examples while correcting their release context.
TC39's completed-proposal record places array grouping in ECMAScript 2024 and Promise.try and synchronous iterator helpers in ECMAScript 2025. They are useful in 2026 without being new features of that year's edition. TC39 completed proposals.
Pattern matching and pipelines need an explicit status check
At this review, the pattern-matching repository identifies Stage 1 and the pipeline-operator repository identifies Stage 2. Their proposed syntax is not a baseline production JavaScript guarantee. A transform may implement a particular proposal revision, which is a separate dependency decision. Pattern-matching proposal, pipeline proposal.
For HTTP response classification, ordinary control flow remains clear and executable:
function classifyStatus(status) {
if (status >= 200 && status < 300) return "success";
if (status === 404) return "not-found";
if (status >= 400 && status < 500) return "client-error";
if (status >= 500 && status < 600) return "server-error";
return "other";
}
console.assert(classifyStatus(404) === "not-found");
console.assert(classifyStatus(503) === "server-error");
Notice the ordering: the specific 404 branch must precede the general 4xx branch. That is the behavior to preserve if a different syntax is adopted later.
Grouping makes the data operation explicit
Object.groupBy and Map.groupBy group iterable values using a callback. Choose the result structure according to the keys and later operations, not merely the shorter spelling. The object result has a null prototype; do not assume it has inherited object methods. TC39 array-grouping proposal and specification.
const orders = [
{ id: 1, status: "pending" },
{ id: 2, status: "shipped" },
{ id: 3, status: "pending" },
];
const grouped = Object.groupBy(orders, order => order.status);
console.assert(grouped.pending.length === 2);
console.assert(Object.getPrototypeOf(grouped) === null);
The operation groups references to existing values. Decide separately whether later code may mutate those objects. Grouping does not provide an immutable snapshot or a database aggregation.
Promise.try unifies one error boundary
Promise.try calls the supplied function and turns a synchronous throw into rejection while adopting an asynchronous result. It does not make CPU-heavy synchronous work run off the main thread. TC39 Promise.try proposal.
function parseInput(text) {
return JSON.parse(text);
}
const result = await Promise.try(() => parseInput('{"enabled":true}'));
console.assert(result.enabled === true);
const failure = await Promise.try(() => parseInput("{"))
.then(() => "unexpected success", error => error.name);
console.assert(failure === "SyntaxError");
This is useful when an API accepts a callback that may return normally, return a promise, or throw. Decide where the caller handles rejection; adding a promise wrapper does not remove the need for an error state.
Lazy iterators stop after enough output
Iterator helpers can avoid creating full intermediate arrays when only part of a sequence is needed. But filtering still examines values that do not pass the predicate. TC39 iterator-helpers proposal.
let examined = 0;
function* numbers() {
for (let value = 0; value < 1000; value++) {
examined++;
yield value;
}
}
const squares = numbers()
.filter(value => value % 2 === 0)
.map(value => value * value)
.take(5)
.toArray();
console.assert(JSON.stringify(squares) === "[0,4,16,36,64]");
console.assert(examined === 9);
Five results require examining nine source values in this example. The earlier claim that only five values were processed was wrong. This distinction matters when reading from an expensive source or reasoning about side effects.
Decorators are a separate compatibility decision
The decorators proposal documents Stage 3 semantics that differ from legacy decorators. Its scope does not make the previous article's parameter-decorator example standard JavaScript. Check the exact framework and transform before migrating decorator code. TC39 decorators proposal.
For every adopted feature, retain a small behavior test in the lowest supported runtime. Syntax transformation and runtime API polyfills solve different problems. A compiler target or editor autocomplete cannot prove that the visitor's browser supplies a built-in method.
The examples here are intentionally small enough to run independently. Their results establish those examples under a stated runtime, not universal support across browsers or a broad performance advantage.

Sardar Mukhshaf
Full-Stack & DevOps Engineer
I build scalable web applications, secure backend systems, and production-ready cloud infrastructure. My engineering focus spans interface design, API architecture, deployment pipelines, and observability. Follow for more deep dives into system architecture, performance engineering, and emerging technologies.
More from the practice
Keep the useful ideas close.
Follow new articles with your preferred RSS reader.
Open the RSS feed ↗


