JavaScript ES6 in 2026: What Still Matters and What You Can Ignore

The ES6 features still worth using daily are let and const, arrow functions, template literals, destructuring, modules, and promises with async/await. Skip var entirely. You can safely ignore most of the rest, like generators, proxies, and symbols, unless a specific problem actually calls for them.
Part of the complete web development guide.
On this page
- The parts of ES6 you should be using every day
- let and const, and why var should be gone
- Arrow functions (and when not to use them)
- Template literals
- Destructuring and default parameters
- Modules: the real win that took years to land
- What people get wrong about ES6
- Things ES6 gave us that you should replace by now
- Do you need to rewrite your old code?
- FAQ
- Is ES6 still relevant in 2026?
- Do I need Babel to use ES6?
- Should I convert my whole codebase to ES modules?
ES6 landed in 2015, and somehow I still see code in 2026 that reads like it was written in 2014. The syntax is old enough to be boring, but the habits around it never fully caught up. If you’re maintaining a codebase or just want to write JavaScript that doesn’t make the next person sigh, here’s what actually holds up.

The parts of ES6 you should be using every day
Most of ES6 is table stakes now. If you’re not using these, you’re making life harder for no reason.
let and const, and why var should be gone
I haven’t written var in years. It’s function-scoped, it hoists in ways that surprise people, and it lets you redeclare the same name twice without complaining. const doesn’t mean the value is frozen, it means the binding can’t be reassigned. That trips people up constantly.
const user = { name: 'Sam' };
user.name = 'Alex'; // fine, you're mutating the object
// user = {}; // TypeError, you're reassigning the binding
// if you actually want it frozen:
const frozen = Object.freeze({ name: 'Sam' });
// frozen.name = 'Alex'; // silently fails in sloppy mode, throws in strict
Default to const. Reach for let only when you’re genuinely reassigning. Never var.
Arrow functions (and when not to use them)
Arrow functions don’t have their own this. That’s the whole point. It fixes the old var self = this; dance, but it also breaks things if you use one as a method or an event handler that needs its own binding.
const counter = {
count: 0,
// don't do this, this.count is undefined
broken: () => { this.count++; },
// do this
works() { this.count++; }
};
// arrows shine in callbacks
[1, 2, 3].map(n => n * 2);
Template literals
String concatenation with + is dead. Template literals handle interpolation and multiline strings cleanly.
const name = 'Commack';
const msg = `Hello from ${name},
this spans two lines.`;
// note: inside a template literal, a ${} that isn't intended as an expression
// still needs escaping if you actually want the dollar sign
Destructuring and default parameters
These two cut a shocking amount of boilerplate. Destructuring works on objects and arrays, and you can rename while you pull values out.
function buildUrl({ host, path = '/', port = 443 } = {}) {
return `https://${host}:${port}${path}`;
}
const [first, second, ...rest] = [1, 2, 3, 4];
const { name: userName, role = 'guest' } = user;

Modules: the real win that took years to land
ES6 gave us import and export, but for years we couldn’t use them in browsers without a bundler. That’s basically settled now. Native ES modules work everywhere, and modern bundlers like Vite and esbuild treat them as the default. If you’re still on CommonJS require() in a new project in 2026, you’re fighting the tooling.
// math.js
export const add = (a, b) => a + b;
export default function multiply(a, b) { return a * b; }
// app.js
import multiply, { add } from './math.js';
One gotcha that still bites people: native ES modules in the browser require the full file path with the extension, and they’re always deferred. No .js omission like Node lets you get away with in some setups.
What people get wrong about ES6
- Confusing ES6 with “modern JS.” ES6 is one spec from 2015. Optional chaining, nullish coalescing, top-level await, and
Array.prototype.at()all came later. Use them too. “ES6” is not the ceiling. - Overusing classes. ES6 classes are sugar over prototypes, not a new object model. If you don’t need inheritance, plain objects and functions are usually clearer.
- Spreading huge arrays in hot loops.
[...bigArray]creates a copy every time. In a tight loop that’s real overhead. Know when you’re paying for it. - Assuming transpilers are still mandatory. For most projects targeting modern browsers, you can ship ES2020+ directly. Check your actual browser support targets before adding a build step you don’t need.
Things ES6 gave us that you should replace by now
A few ES6 patterns have better answers in 2026:
Promisechains: still fine, butasync/await(ES2017) reads better for anything sequential.Object.assign({}, a, b): use the spread operator{ ...a, ...b }instead.- Manually writing
indexOf() !== -1:Array.prototype.includes()is clearer and handlesNaNcorrectly.
Do you need to rewrite your old code?
No. That’s the honest answer. If it works and it’s tested, leave it. Rewrite the files you’re already touching for other reasons, and clean them up as you go. A wholesale “modernize everything” pass is how you introduce bugs nobody asked for.
The exception is when you’re hiring or onboarding. Code that reads like 2014 makes it harder to find people who want to work in it, and it slows down every new developer. If you’re staring at a codebase that’s drifted and you want a second set of eyes, that’s the kind of work I do through custom web development for teams around Long Island and beyond. Sometimes it’s a refactor, sometimes it’s just a plan for what to touch first.
FAQ
Is ES6 still relevant in 2026?
Yes, but it’s the floor, not the goal. The syntax is stable and universally supported. The newer features built on top of it (async/await, optional chaining, top-level await) are what separate current code from code that’s just technically working.
Do I need Babel to use ES6?
Almost never for modern browsers. Native support has been complete for years. You might still want a transpiler if you support very old browsers or specific embedded environments, but check your actual targets before adding the complexity.
Should I convert my whole codebase to ES modules?
Only if you’re already changing your build setup. Mixing CommonJS and ES modules works but gets confusing fast. If your current setup is stable, converting for its own sake isn’t worth the risk. Do it as part of a larger change, not as a standalone project.


