JavaScript Tactics That Actually Matter in 2026

In 2026 the JavaScript that matters is mostly platform built-ins: optional chaining, nullish coalescing, structuredClone, and fetch with AbortController. I reach for libraries only when the browser still can't do the job. Skip the rewrite, update the old code in place.
Part of the complete web development guide.
On this page
- Start with the boring wins
- Stop reaching for a library for things the platform does now
- A fetch wrapper worth keeping
- Where the real performance lives
- Move heavy work off the main thread
- TypeScript is not optional anymore
- How I modernize an old codebase without a rewrite
- What I have stopped doing
- FAQ
- Do I need to rewrite my old JavaScript project?
- Is TypeScript worth it for a small site?
- What is the single biggest speed win for most sites?
Every few years a batch of JavaScript advice gets recycled as if it were new. Some of it ages fine. A lot of it does not, and I still see 2016 habits in codebases I get handed in 2026. Here is what I actually reach for now, what I have stopped using, and how I move an old project forward without a rewrite that never ships.
Start with the boring wins
Before anything clever, make sure the basics are current. These are not exciting, but they remove whole categories of bugs.
- Optional chaining and nullish coalescing.
?.and??have been standard for years. If your code is still full of&&guards, you are writing more than you need. - Use
??instead of||for defaults.||treats0and""as missing. That is a real bug in pricing, counts, and form fields. structuredClonefor deep copies. No moreJSON.parse(JSON.stringify(obj)), which silently destroys dates,Map,Set, andundefined.- Top-level await in modules. If you are on a modern bundler or native ESM, you can await during module init instead of wrapping everything in an async IIFE.
// Old habit: breaks on 0 and ""
const qty = input.qty || 1;
// Current: only falls back when the value is null or undefined
const qty = input.qty ?? 1;
// Deep copy that respects dates and Maps
const snapshot = structuredClone(cart);
Stop reaching for a library for things the platform does now
A lot of dependencies exist because the browser could not do the job a decade ago. That is no longer true for most of them.
- Fetching data:
fetchwithAbortControllercovers what people used axios for. Add a small wrapper for timeouts and JSON parsing and you are done. - Dates:
Intl.DateTimeFormatand the newerTemporalAPI (shipping across engines in 2026) handle formatting and timezone math that used to require Moment or a pile of helpers. - Class toggling and DOM work:
classList,querySelectorAll, andelement.animate()mean jQuery is dead weight in new projects.
Dropping a dependency is not about purity. It is about one less thing to patch when a CVE lands, and one less thing in your bundle.
A fetch wrapper worth keeping
async function getJSON(url, { timeout = 8000, ...opts } = {}) {
const ctrl = new AbortController();
const timer = setTimeout(() => ctrl.abort(), timeout);
try {
const res = await fetch(url, { ...opts, signal: ctrl.signal });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
} finally {
clearTimeout(timer);
}
}
That is roughly fifteen lines. It replaces a library, and you can read all of it.
Where the real performance lives
Most “make it faster” requests are not solved by micro-optimizing a loop. They are solved by sending less and doing less on the main thread.
- Ship less JavaScript. The fastest code is code the browser never downloads. Check your bundle with a real analyzer before you optimize anything.
- Keep the main thread free. Long tasks block clicks and scrolling. Move heavy parsing or math into a Web Worker.
- Render less. If you are on a framework, the wins come from not re-rendering, not from a faster render.
- Respect the network. Cache with the Cache API or a service worker for repeat visits. On mobile connections around Long Island and everywhere else, this matters more than shaving bytes off a vendor chunk.
Move heavy work off the main thread
// worker.js
self.onmessage = (e) => {
const result = crunch(e.data); // CPU-heavy work
self.postMessage(result);
};
// main.js
const worker = new Worker(new URL('./worker.js', import.meta.url), { type: 'module' });
worker.postMessage(payload);
worker.onmessage = (e) => render(e.data);
The UI stays responsive while the worker grinds. This single change fixes a lot of “the page feels janky” complaints.
TypeScript is not optional anymore
I have watched too many production bugs that a type checker would have caught at build time. If you are starting anything in 2026, use TypeScript. If you have a large plain JS codebase, do not convert it all at once. Turn on checkJs, add types to the files you touch, and let it spread. You get most of the benefit within a few months without a freeze on feature work.
How I modernize an old codebase without a rewrite
Full rewrites fail often enough that I treat them as a last resort. What works instead:
- Get tests around the risky parts first. You cannot safely refactor what you cannot verify.
- Update tooling before logic. Newer bundler, newer Node, newer lint rules. That surfaces problems cheaply.
- Replace one dependency at a time. Swap the date library, ship it, then swap the HTTP client.
- Delete code. The best modernization is removing a feature nobody uses.
I do this kind of work on custom web development projects, and the pattern holds whether the app is a marketing site or an internal tool. Slow, verifiable steps beat a big bang every time.
What I have stopped doing
- Reaching for a framework for a page that needs a form and a menu. Plain HTML and a bit of JS is faster to build and faster to load.
- Chasing every new runtime. Pick boring, well-supported tools and spend the saved time on the actual product.
- Clever one-liners. Code is read far more than it is written. Clarity wins.
FAQ
Do I need to rewrite my old JavaScript project?
Almost never. Update the tooling, add tests around the fragile parts, and modernize file by file. Rewrites usually cost more and ship later than expected.
Is TypeScript worth it for a small site?
For a static marketing page, probably not. For anything with data, forms, or more than one developer, yes. The build-time errors pay for the setup quickly.
What is the single biggest speed win for most sites?
Sending less JavaScript. Audit the bundle, remove what you do not use, and move heavy work to a worker before you touch anything else.


