The JavaScript Problems We Learned To Accept (And ES2026 Finally Fixed Them)

The JavaScript Problems We Learned To Accept (And ES2026 Finally Fixed Them)

Dates, math, JSON, and cleanup were always fragile… I assumed that was normal until ES2026 proved it wasn’t.

Mutasim Billah Toha

Photo by Vitaly Gariev on Unsplash

Remember the last time you tried to add two numbers in JavaScript and got 0.30000000000000004 instead of 0.3? Or when you needed to work with dates and timezones, spent three hours debugging, then just imported Moment.js and called it a day?

Yeah, me too.

Here’s the thing: JavaScript has been silently carrying around some embarrassing baggage from the ’90s. But ES2026 is about to drop the mic with features that’ll make you say, “wait, JavaScript can do that NOW?”

The Date Object That Broke a Million Hearts

Let’s talk about JavaScript’s Date object. It’s… how do I put this nicely? It’s terrible.

I once watched a developer discover that new Date(0) and new Date("0") give you different dates. The look on their face was somewhere between confusion and existential crisis. That’s because Date treats zero as a timestamp but treats “0” as… I honestly don’t know, and neither does JavaScript.

Date Magic

Enter Temporal: The hero we’ve been waiting for.

Temporal isn’t just a replacement for Date. It’s JavaScript finally admitting “yeah, we messed that up” and actually fixing it. It handles timezones properly. It understands calendars. It doesn’t make you want to throw your laptop out the window when working with durations.

Here’s what blew my mind: Temporal has 4,000 tests. For comparison, most JavaScript features have a couple of hundreds. That’s how serious they are about getting this right.

// Calculate flight duration between timezones
const departure = “2025-06-01T08:30:00-04:00[America/New_York]”;
const arrival = “2025-06-01T22:15:00+02:00[Europe/Paris]”;

const departureTZ = Temporal.ZonedDateTime.from(departure);
const arrivalTZ = Temporal.ZonedDateTime.from(arrival);
console.log(departureTZ.until(arrivalTZ).toString());
// Output: “PT9H45M” (9 hours, 45 minutes)

No library. No headache. Just works.

Firefox has already rolled out support. Chrome is scheduled for January 2026. The date nightmare is finally ending.

Math That Actually Makes Sense

You know what’s fun? Trying to sum a list of floating-point numbers in JavaScript.

Just kidding. It’s not fun at all.

I watched a junior developer write a budget calculator once. They summed up expenses perfectly in their loop. The math looked flawless. But JavaScript’s floating-point precision turned $100.50 into $100.49999999999997.

The user’s budget app told them they were 3 cents off. They weren’t. JavaScript was just being JavaScript.

ES2026 brings Math.sumPrecise a method that actually sums numbers correctly. It uses a slower but more accurate algorithm that handles floating-point precision properly. Yes, it’s slower than regular addition. But when correctness matters more than speed (budgets, financial calculations, scientific data), that’s a tradeoff you’ll gladly make.

Before ES2026:

let total = 0;
prices.forEach(price => total += price);
// Hope for the best, prepare for weird decimals

With ES2026:

const total = Math.sumPrecise(prices);
// Actually correct

Simple. Reliable. What math should’ve been all along.

The Cleanup Problem You Didn’t Know You Had

Picture this: You open a database connection. You run some queries. Your code throws an error halfway through.

Did you remember to close that connection? Did it actually close, or is it sitting there, eating resources like a forgotten Netflix tab?

Most developers solve this with try-finally blocks. You acquire the resource up top, scroll down 200 lines, and hopefully remember to clean it up in the finally block. It works, but it’s messy and error-prone.

ES2026 introduces using blocks automatic resource cleanup that actually makes sense:

{
using connection = new DatabaseConnection(“myDB”);
connection.query(“SELECT * FROM users”);
// Boom! Error thrown here
} // Connection automatically closes, even with the error

No try-finally. No forgetting. The cleanup happens automatically when the code block ends, whether it completes normally or crashes spectacularly.

I asked Bloomberg engineer Ashley Claymore about this. She said: “You see that a resource is required, and you’re hoping it gets cleaned up, and you scroll and scroll until you find the finally block… Now you get it for free.”

This is especially crucial for things like database connections with hard limits. Your garbage collector doesn’t know your database only allows 256 connections. It’ll let your code leak connections until everything breaks. using blocks fix that.

Base64 Without the Library Bloat

Here’s a weird one: JavaScript has arrays for binary data (Uint8Array), but no built-in way to encode them as base64.

Need to handle SSH keys? Embed a small image? You’d reach for a library.

With ES2026, you just:

const encoded = myData.toBase64();
const decoded = Uint8Array.fromBase64(encodedString);

Done. No NPM install, no wondering if the library is still maintained, no adding 50KB to your bundle for two functions.

The JSON Problem You’ve Been Living With

JSON.parse is great until it isn’t.

Parse a number like 999999999999999999 and JavaScript rounds it to 1000000000000000000. Parse a date and it adds weird empty seconds. Try to parse a BigInt and JavaScript just refuses.

Why? Because JSON has arbitrary precision and JavaScript doesn’t. The conversion is lossy.

ES2026’s JSON.parse Source Text lets you grab the raw JSON and handle it however you want:

const parsed = JSON.parse(jsonString, (key, value, context) => {
if (key === ‘bigNumber’) {
return BigInt(context.source); // Use the raw source
}
return value;
});

Finally, you can parse JSON without losing precision. It took a proposal from 2018 to get here, but we made it.

Performance Wins You’ll Actually Feel

Remember when you imported an entire library just to use one function from it? Your browser remembers. It’s still loading that 500KB bundle.

Import defer changes the game:

import defer * as utils from ‘./heavy-module.js’;

// Module doesn’t load yet…
// Still not loaded…
utils.someFunction(); // NOW it loads, right when you need it

Bloomberg’s terminal already uses this pattern. Rob Palmer from Bloomberg said it shaves “hundreds of milliseconds” off load times for large applications.

The module only loads when you actually touch it. Everything stays synchronous (unlike dynamic imports), so you can drop it into existing code without rewriting everything.

Browser implementations are underway, with support expected in 2026. Your startup time is about to get faster.

The Weekend Isn’t Sunday-Monday Everywhere

Quick question: What’s the first day of the week?

If you said Monday, you’re right in most of Europe. If you said Sunday, you’re right in the US. If you said Saturday, you’re right, in parts of the Middle East.

Now: What days are the weekend? Saturday-Sunday? Friday-Saturday? Just Friday? Just Sunday?

If you’re building a calendar app, you need to know this. And the answer changes based on where your user is.

Intl.Locale pulls all this from Unicode locale data:

const locale = new Intl.Locale(‘en-US’);
console.log(locale.weekInfo.firstDay); // 7 (Sunday)
console.log(locale.weekInfo.weekend); // [6, 7] (Sat, Sun)

No more maintaining a database of “which countries have which weekends.” JavaScript knows.

The Little Wins That Add Up

ES2026 also brings a bunch of smaller improvements that’ll make your code cleaner:

Error.isError() Check if something is actually an error (works across iframes and extensions, unlike instanceof)

Iterator.concat() Chain iterators together like every other language, lets you do

Array.fromAsync() Convert async iterables to arrays without writing a loop

Map.upsert() Update-or-insert in one call (yes, JavaScript is finally getting this basic database operation)

None of these are flashy. All of them remove friction.

What This Actually Means

ES2026 isn’t just adding features. It’s JavaScript growing up.

The Temporal API alone removes thousands of lines of library code from web apps. Import defer makes load times faster without rewriting your architecture. Explicit resource management prevents an entire class of bugs.

And the best part? Most of this stuff is already available in browsers or tools like TypeScript. You can start using it now.

The JavaScript that shipped in 1995 was held together with duct tape and good intentions. Thirty years later, we’re finally peeling off the tape.

In five years, we’ll look back at Date and floating-point hacks the way we look at document.write today. Obvious mistakes we somehow lived with for decades.

See how it feels to write JavaScript that doesn’t fight you.

Because honestly? We’ve waited long enough.