JavaScript keeps changing all the time. Not always in huge, flashy ways, sometimes it’s the small and subtle things that quietly make your life easier. The ES (ECMAScript) spec (which is just the standardized version of JavaScript) gets an update every year, and if you don’t keep an eye on it, you might miss some legit helpful features.
This post is a quick run-through of the stuff that dropped in ES2023 (the 14th edition of ECMAScript), plus a couple of features that are likely to land in 2024 or shortly after. It’s not a deep dive into every technical detail, just the good and interesting stuff, with code samples you can actually use in your day to day projects.
Let’s dive in! 🏊
First, a Quick Note on How JavaScript Gets New Stuff
New JavaScript features go through a proposal process managed by the TC39 committee. It’s a group of engineers from various companies (think: browser makers, Node folks, etc.) who argue about how things should work so you don’t have to.
There are 5 “stages”:
- Stage 0 – someone has an idea
- Stage 1 – the idea gets a champion
- Stage 2 – early draft
- Stage 3 – real implementations start
- Stage 4 – 🚀 it’s done and in the spec
Only Stage 4 stuff is essentially “official.” If you want to nerd out more, the TC39 proposals repo is the place.
What’s New in ES2023 (Stuff You Can Use Right Now)
findLast()
and findLastIndex()
Ever need to grab the last item in an array that matches a condition? You probably reversed the array or looped it backward manually. Now you don’t have to.
const posts = [
{ title: "Old post", published: false },
{ title: "Draft", published: false },
{ title: "Latest post", published: true },
];
const latest = posts.findLast(post => post.published);
findLast()
= last matching itemfindLastIndex()
= index of that item
Same deal as find()
and findIndex()
, just works from the end. Super handy.
New Array Methods That Don’t Mutate
Arrays in JavaScript are sneaky — methods like .sort()
or .reverse()
actually change the original array. That’s bad news if you’re working with state or writing functional code.
Now we’ve got immutable versions:
const nums = [3, 1, 2];
const sorted = nums.toSorted(); // [1, 2, 3]
const reversed = nums.toReversed(); // [2, 1, 3]
Also:
toSpliced()
= likesplice()
, but doesn’t mutatewith()
= update a value at a specific index
const updated = nums.with(0, 99); // [99, 1, 2]
These seem small, but they’re a big win for code that’s easier to reason about and less likely to break stuff unexpectedly.
Symbols as WeakMap Keys
This one’s a little more niche, but before ES2023, you couldn’t use a Symbol
as a key in a WeakMap
. Now you can:
const secretKey = Symbol('secret');
const wm = new WeakMap();
wm.set(secretKey, 'some value');
More options for managing private-ish data without memory leaks. Useful if you’re deep in the weeds with internals, libraries, or frameworks.
Hashbang (Shebang) Support
Writing CLI tools in Node? You’ve probably written this before at the top of a file:
#!/usr/bin/env node
That’s a hashbang (aka shebang), and now JavaScript officially supports it in the spec. Nothing earth-shattering, but it’s nice to see things used in the real world getting formal support.
What’s Probably Coming in ES2024+
Let’s talk future. These features aren’t final yet, but they’re in Stage 3 or close — which means they’re well on their way.
Temporal: A Fix for JavaScript’s Broken Date Handling
Everyone hates Date
. It’s weird, inconsistent, and does a terrible job with time zones and durations.
The Temporal API is meant to replace it:
const now = Temporal.Now.plainDateTimeISO();
const inAWeek = now.add({ days: 7 });
It handles calendars, time zones, durations — the works. If you’re building anything that cares about time (scheduling, billing, etc.), you’ll want this.
Pattern Matching
Imagine switch
statements, but smarter — and able to destructure and match shapes:
match (event) {
{ type: 'click' } => handleClick(),
{ type: 'submit', formData } => handleSubmit(formData),
_ => handleDefault()
}
Still in proposal form, but shaping up nicely. If you’ve used pattern matching in other languages (like Rust or Haskell), you know how powerful this can be.
The Pipeline Operator (|>
)
This one’s controversial. The basic idea is to make function chaining easier to read:
const result = input
|> sanitize
|> validate
|> submit;
Instead of deeply nested calls, you get a clear, top-to-bottom flow. Some devs love it. Others aren’t sold. Still, if it makes it in, it’ll be a cleaner way to compose functions.
Record & Tuple (Immutable, Value-Based Data)
JS objects and arrays are reference-based and mutable. That’s fine, until it isn’t.
Records and Tuples are immutable, deeply frozen, and compared by value:
const user = #{
name: 'Chris',
age: 32
};
const colors = #['red', 'green', 'blue'];
Notice the #
— that’s part of the syntax. Not finalized yet, but super interesting for functional programming and places where data shouldn’t change.
How to Try This Stuff Now
Want to play with these features before they’re fully supported in browsers?
- Babel: Add plugins for newer syntax.
- core-js: Polyfills for standard library stuff.
- TypeScript: Some proposals are available behind flags or via types.
You’ll need to check individual support, but most tools make it pretty painless to experiment.
Final Thoughts
JavaScript is evolving — sometimes in big ways, sometimes in ways that seem small but solve real annoyances. If you’re building stuff in JS and haven’t looked past ES6, you’re missing out on a lot of improvements.
Don’t feel like you need to learn every new feature the second it drops. But it’s worth checking in once a year to see what’s changed — and maybe refactor that reverse().find()
combo into something way cleaner.
If you found something here useful, cool. If I missed something you’re excited about, hit me up or drop it in the comments.
Resources
Part of the Series
This is part of the Ultimate JavaScript Tutorial series.
🤔 What do you think?