The three pillars of JavaScript bloat
Perceived causes of JS bloat
- Many see the root cause as “add features fast” culture: it’s always easier to
npm installthan to remove or refactor. - Others argue the main issue isn’t polyfills or micro-packages alone, but an overall lack of restraint and constant trend-chasing.
- Some distinguish between “necessary” extra code (real compatibility needs) and “optional” bloat added by default.
Micro-packages and “atomic architecture”
- Widespread criticism of tiny utility packages (e.g., is-even/is-odd, type-checkers) that could be inlined as a few lines of code.
- These add install time, metadata overhead, bundle size, and attack surface for almost no benefit.
- Some say this pattern is driven by ego or financial incentives (download metrics, sponsorship schemes), not purely technical reasons.
- A minority defends small, focused crates in other ecosystems (like Rust) as more disciplined and less extreme than npm.
Polyfills, ponyfills, and legacy support
- Large part of bloat attributed to supporting very old JS engines (ES3, ancient Node, IE-era browsers).
- Commenters argue most users are on modern browsers; polyfill stacks are often retained long after they’re needed.
- Others emphasize edge cases: old Android devices, locked-down or weird browsers, “on-demand” gig platforms, and poor users stuck on old hardware.
- There’s debate over where to draw the cutoff; some advocate following Node’s EOL schedule and letting truly old environments fend for themselves.
Frameworks, tooling, and ecosystem churn
- React, Webpack, and complex build stacks (Babel, TypeScript, various bundlers) are blamed for huge dependency trees and confusion (CJS vs ESM, require vs import).
- Some say frameworks solve real problems for complex, interactive UIs; others think most “websites” don’t need SPA-style tooling at all.
- Tooling upgrades for legacy projects are seen as so painful that teams keep ancient configs, perpetuating bloat.
Security, supply chain, and incentives
- Every micro-package is an additional supply-chain risk; trivial utilities are unlikely to be audited.
- Recent supply-chain incidents are cited as examples of how easy it is to slip malware into widely used tiny packages.
- Allegations that some maintainers aggressively add their own small packages as transitive deps, inflating download counts and sponsorship income.
Standard library vs dependencies
- Several argue JS’s historical lack of a rich, cohesive standard library pushed people toward micro-packages.
- Others counter that modern web APIs plus built-in ECMAScript features already cover most needs; what’s missing is discipline, not primitives.
- There’s disagreement over how much is still truly “missing” (e.g., clamp, richer math/stats, functional utilities).
Minimal / dependency-free / vanilla approaches
- Multiple commenters report success building apps with few or no runtime dependencies, relying on:
- Modern JS/CSS, web components, and browser APIs.
- Server-side rendering plus small targeted JS for interactivity.
- Claimed benefits: smaller bundles, fewer CVEs, simpler debugging, easier audits, and less maintenance pain.
- Critics note that for some domains (maps, complex UIs) large dependencies remain practical and hard to replace.
Broader perspectives and comparisons
- Comparisons with Rust, Python, C, and C++: all can accumulate large dep trees once a convenient package ecosystem appears.
- Some see JS bloat as cultural: many developers are self-taught, heavily tutorial-driven, and encouraged to “never reinvent the wheel.”
- Others stress that vanilla techniques and careful dependency choices scale better than assumed, but are under-taught and counter to prevailing norms.