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 install than 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.