When we talk about website carbon, images get most of the attention because they dominate page weight. Fair enough. But there is a strong argument that JavaScript deserves equal concern — not because of raw file size (though that is growing), but because JavaScript costs more energy per byte than any other web content type.

An image is downloaded and decoded once. JavaScript is downloaded, parsed into an abstract syntax tree, compiled to bytecode (or machine code via JIT), and then executed — potentially running thousands of operations that consume CPU, memory, and battery. Byte for byte, JavaScript is the most energy-intensive thing you send to a browser.

The Numbers

The median website in 2026 ships approximately 500KB of JavaScript (compressed, so roughly 1.5-2MB uncompressed). The 90th percentile exceeds 1.5MB compressed. Single-page applications routinely ship 2-3MB.

Research from Mightybytes and the Green Web Foundation suggests that JavaScript parsing and execution can consume 3-5x more CPU energy per byte than rendering images. On a mid-range mobile device, parsing 1MB of JavaScript can take 2-4 seconds of active CPU time. That is 2-4 seconds of battery drain, heat generation, and energy consumption — per page load.

Compare that to a 1MB image: decoded in perhaps 50-100 milliseconds. The raw download cost is similar, but the processing overhead is wildly different.

Where All That JavaScript Comes From

On a typical commercial website, JavaScript comes from three sources:

Frameworks and libraries (30-40%). React, Angular, Vue, jQuery, Bootstrap JS, utility libraries like Lodash — the foundational code that the site is built on. For SPAs, the framework alone can be 100-300KB compressed.

Third-party scripts (30-50%). Analytics, advertising, chat widgets, A/B testing, social embeds, consent management. Each script is small individually (20-100KB), but collectively they often outweigh your own application code. And you do not control their size — the vendor can ship a larger version at any time.

Application code (20-30%). Your actual business logic, UI components, page-specific functionality. Often the smallest of the three categories, which tells you something about where the real optimization opportunities lie.

The Framework Question

This is where sustainability conversations get contentious. Modern JavaScript frameworks are enormously productive for development teams. React, Next.js, Nuxt, SvelteKit — they enable complex, interactive web applications that would be extremely difficult to build otherwise.

But they come with a baseline cost. A minimal React application — before you write a single component — ships roughly 130KB of framework JavaScript (compressed). Add a router, state management, and a UI library, and you are at 200-400KB before any application code.

For a highly interactive web application (dashboards, editors, collaboration tools), this cost is justified. The framework enables functionality that users need and cannot be replicated with simpler technology.

For a content website (blog, marketing site, documentation, corporate pages), the framework cost is harder to justify. A blog post does not need React. A marketing page does not need Angular. Server-rendered HTML with minimal JavaScript interactivity serves the same user need at a fraction of the energy cost.

The sustainable approach: match the technology to the need. Use frameworks where interactivity demands it. Use server-side rendering and progressive enhancement where content is primary.

Practical Strategies to Reduce JavaScript

Audit First

Before optimizing, understand what you have. Browser DevTools (Coverage tab in Chrome) shows exactly how much of your loaded JavaScript is actually executed. It is common to find that 50-70% of loaded JS is never used on any given page.

Webpack Bundle Analyzer, Source Map Explorer, or Lighthouse's "Reduce unused JavaScript" audit provide detailed views of what is in your bundles and what can be removed.

Code Split

Instead of loading the entire application on every page, split code by route (each page loads only its own code), by component (heavy components load on demand), and by interaction (load the modal code when the user clicks the modal trigger, not on page load).

Modern bundlers (webpack, Rollup, Vite) support dynamic import() for code splitting. Frameworks like Next.js, Nuxt, and SvelteKit handle route-based splitting automatically.

Tree Shake

Tree shaking eliminates unused exports from your bundles. If you import one function from Lodash, tree shaking ensures you do not ship the entire library. This requires ES modules (import/export syntax), a bundler that supports tree shaking, and libraries that are tree-shakeable (not all are — check before adopting).

Replace Frameworks with Lighter Alternatives

For content-heavy sites that do not need full SPA functionality: Astro renders to static HTML with zero JavaScript by default, adding JS only for interactive "islands." 11ty (Eleventy) is a static site generator that produces clean HTML with minimal overhead. Alpine.js provides reactive interactivity at 15KB compressed — a fraction of full frameworks. htmx enables dynamic behavior through HTML attributes with 14KB of JavaScript.

Defer and Async Third-Party Scripts

Third-party scripts that are not critical for initial page render should be deferred or loaded asynchronously. Use async for scripts that can run in any order. Use defer for scripts that need to run after HTML parsing. Load non-essential scripts only after user interaction (lazy-load chat widgets, social embeds, etc.).

Use Native Browser APIs

Modern browsers have made many JavaScript libraries obsolete. document.querySelector() replaces jQuery selectors. Fetch API replaces axios for most use cases. CSS animations replace jQuery/GSAP for many transitions. Intersection Observer replaces scroll-position libraries for lazy loading and visibility detection. dialog element replaces modal libraries for basic modals.

Measuring JavaScript's Carbon Impact

Standard carbon calculators (including Carbon Badge) measure total data transfer, which captures JavaScript's download cost but not its processing overhead. The true energy cost of JavaScript is higher than the data transfer alone would suggest.

For a more complete picture, combine carbon measurement with Lighthouse Performance score (which penalizes heavy JavaScript), Total Blocking Time (measures how long JavaScript blocks the main thread), and JavaScript coverage analysis (how much loaded JS is actually used).

A site that scores well on all four metrics — low carbon per page view, high Lighthouse score, low TBT, and high JS coverage — is genuinely efficient.

The Bigger Picture

The web's JavaScript problem is not just a sustainability issue — it is an accessibility issue (heavy JS breaks on slow connections and old devices), a performance issue (users on mid-range phones experience painful load times), and an equity issue (the cost of data transfer is proportionally higher in lower-income countries).

Reducing JavaScript makes the web faster, more accessible, cheaper to use, and greener. There are not many optimizations with that many simultaneous benefits. Ship less JavaScript. Your users, their devices, and the planet will thank you.