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
withstatements,__proto__, andString.prototype.substrshould 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:
withstatements — Banned in strict mode since ES5. They create ambiguous scope and break optimizations.__proto__— UseObject.getPrototypeOf()andObject.setPrototypeOf()instead.String.prototype.substr— Deprecated. Useslice()orsubstring().- 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 manipulation —
querySelector,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()andMap.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 modules —
import 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.
Discover how at OpenReplay.com.
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
ResizeObserverhacks. :has()selector — Parent selection without DOM traversal.- Scroll-linked animations —
animation-timeline: scroll()replaces scroll event listeners. - View transitions — Native page transition effects.
Every scroll listener you remove is a main-thread win.
Stop Using Mutation Events and Third-Party Cookie Assumptions
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.