Back

Things to Stop Doing in JavaScript in 2025

Things to Stop Doing in JavaScript in 2025

JavaScript moves fast. Code patterns that felt modern three years ago now ship unnecessary bytes, ignore platform improvements, or rely on deprecated APIs. If you’re building production web apps in 2025, here are the JavaScript anti-patterns to avoid—and what to reach for instead.

Key Takeaways

  • Deprecated features like with statements, __proto__, and String.prototype.substr should be replaced with modern alternatives.
  • Legacy libraries such as jQuery, Moment.js, and Lodash can often be replaced with native browser APIs and ES2023–ES2025 features.
  • Modern CSS now handles many tasks that previously required JavaScript, including container queries, the :has() selector, and scroll-linked animations.
  • Native ESM and lightweight bundlers like Vite have made CommonJS and RequireJS obsolete for new frontend projects.

Stop Using Deprecated Language Features

Some JavaScript features have been deprecated or superseded for years, yet they persist in codebases through copy-paste and habit.

Drop these from your vocabulary:

  • with statements — Banned in strict mode since ES5. They create ambiguous scope and break optimizations.
  • __proto__ — Use Object.getPrototypeOf() and Object.setPrototypeOf() instead.
  • String.prototype.substr — Deprecated. Use slice() or substring().
  • Legacy RegExp statics like RegExp.$1 — These are non-standard and unreliable across engines.

These aren’t edge cases. Linters flag them for good reason. Modern JavaScript patterns assume you’ve moved on.

Stop Reaching for Legacy Libraries by Default

jQuery, Moment.js, Lodash, and RequireJS solved real problems—in 2015. Today, the platform covers most of their use cases natively.

What to do instead:

  • DOM manipulationquerySelector, querySelectorAll, and modern DOM APIs handle what jQuery once did.
  • Date handling — The Temporal API is coming. Until full support lands, use date-fns or native Intl.DateTimeFormat.
  • Utility functions — ES2023–ES2025 features like Object.groupBy(), new Set methods (.union(), .intersection()), and iterator helpers (.map(), .filter() on iterators) replace most Lodash imports.
  • Module loading — Native ESM and import() make RequireJS and AMD obsolete.

Shipping a 30KB library for functionality the browser provides free is a frontend mistake to stop in 2025.

Stop Ignoring ES2023–ES2025 Features

The language has evolved significantly. These features are stable or nearly so:

  • Object.groupBy() and Map.groupBy() — Group arrays without external libraries.
  • Iterator helpers — Chain .map(), .filter(), .take() directly on iterators.
  • New Set methods.union(), .intersection(), .difference(), .isSubsetOf().
  • RegExp.escape() — Safely escape strings for regex patterns.
  • Import attributes and JSON modulesimport data from './config.json' with { type: 'json' }.
  • Top-level await — Use it in modules without wrapping everything in async IIFEs.

Check caniuse.com and your target browsers, but don’t default to polyfills for features that shipped two years ago.

Stop Using JavaScript for What CSS Now Handles

Modern CSS has absorbed functionality that once required JavaScript. Using JS for these creates unnecessary complexity and hurts performance.

Let CSS handle:

  • Container queries — Responsive components without ResizeObserver hacks.
  • :has() selector — Parent selection without DOM traversal.
  • Scroll-linked animationsanimation-timeline: scroll() replaces scroll event listeners.
  • View transitions — Native page transition effects.

Every scroll listener you remove is a main-thread win.

Mutation Events (DOMSubtreeModified, DOMNodeInserted) are deprecated and perform poorly. Use MutationObserver instead—it’s been stable for over a decade.

Third-party cookies are effectively dead for tracking and cross-site auth flows. Chrome’s deprecation timeline has shifted, but Safari and Firefox blocked them years ago. Build authentication flows with first-party cookies, tokens, or federated identity. Don’t architect around assumptions that break in half your users’ browsers.

Stop Starting New Projects with CommonJS

If you’re writing browser code in 2025 and reaching for require() or heavy webpack configurations, pause. Native ESM works everywhere that matters. Lighter bundlers like Vite and esbuild handle the remaining edge cases with minimal configuration.

CommonJS still has its place in Node.js libraries targeting older environments. For new frontend code, it’s legacy baggage.

Conclusion

JavaScript best practices in 2025 aren’t about chasing trends—they’re about recognizing when the platform has caught up to your dependencies. Every deprecated feature you remove, every unnecessary library you drop, and every CSS-native solution you adopt makes your code smaller, faster, and easier to maintain.

Audit your current projects. Check your imports. Question whether that utility function needs a library or just a native method you haven’t learned yet. The modern JavaScript patterns are already here—you just have to use them.

FAQs

Yes, but proceed carefully. Modern browsers support querySelector, fetch, and other APIs that replace jQuery's core functionality. For existing projects, audit your jQuery usage first and replace calls incrementally. New projects should avoid jQuery entirely since native alternatives are now well-supported and more performant.

The Temporal API is at Stage 3 in the TC39 process and available behind flags in some browsers. Full cross-browser support is expected soon, but for production code today, use date-fns or native Intl.DateTimeFormat. Monitor caniuse.com for updates before adopting Temporal without polyfills.

For most use cases, no. Native JavaScript now includes Object.groupBy, new Set methods, and iterator helpers that cover common Lodash functions. However, Lodash remains useful for deep cloning, complex object manipulation, or when targeting older environments. Import only the specific functions you need rather than the entire library.

Start by updating your package.json with type set to module. Replace require statements with import syntax and module.exports with export. Update file extensions to .mjs if needed, or configure your bundler accordingly. Tools like Vite and esbuild simplify this transition significantly for frontend projects.

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay