Building Zero-JavaScript Websites: Why Less Is More
How reducing front-end client JS payloads drastically increases speed, battery life, and SEO performance.
Listen to Article
PlayingClick play to listen to audio narration

Table of Contents
- •The Hidden Cost of Client-Side JavaScript
- •Achieving Interactivity with Modern CSS
- •Smooth Accordions with <details>
- •CSS Scroll-Driven Animations
- •Frameworks That Support Zero-JS Defaults
- •What “Zero JavaScript” Actually Means
- •Building a Collapsible FAQ with Zero JavaScript
- •CSS-Only Dark Mode
- •When to Accept a JavaScript Dependency
- •Performance Impact
- •Building Zero-JS Pages in Astro
Modern websites often bundle megabytes of client-side JavaScript for features that could easily be handled with modern CSS and server-side rendering.
The Hidden Cost of Client-Side JavaScript
Heavy JavaScript bundles cause:
- High CPU Utilization: Parsing and executing JS consumes mobile device CPU and battery.
- Network Latency: Large bundles degrade performance on 3G/4G connections.
- Poorer Accessibility: Over-reliance on JS-driven renders often breaks accessibility tree defaults.
Achieving Interactivity with Modern CSS
Many legacy JS tricks are now natively supported in pure CSS:
Smooth Accordions with <details>
<details class="p-4 border rounded">
<summary class="font-bold cursor-pointer">Click to toggle content</summary>
<p class="mt-2">No JavaScript required for accordion state!</p>
</details>
CSS Scroll-Driven Animations
CSS scroll animations eliminate the need for heavy JS scroll libraries.
Frameworks That Support Zero-JS Defaults
- Astro: Strips JavaScript by default unless explicitly instructed (
client:load). - Eleventy: Pure static HTML generator.
- SvelteKit / Next.js: Support static rendering modes.
Build leaner, faster, and more accessible websites by prioritizing zero-JS architecture.
What “Zero JavaScript” Actually Means
A zero-JS site delivers pure HTML and CSS to the browser. No JavaScript bundle downloads, no hydration cost, no JavaScript parse time. The browser renders markup directly.
This is not the same as no interactivity. CSS alone supports:
- Animated transitions and keyframes
- Responsive layouts via media/container queries
- Hover and focus states
- The
<details>/<summary>disclosure pattern - Form validation using
:valid/:invalidpseudo-classes - The
<dialog>element (requires minimal JS for focus management, but no framework)
Building a Collapsible FAQ with Zero JavaScript
<details class="faq-item">
<summary>What is static site generation?</summary>
<p>
Static site generation pre-builds HTML pages at compile time.
The server delivers pre-rendered files; no runtime computation occurs per request.
</p>
</details>
details.faq-item summary {
cursor: pointer;
font-weight: 600;
padding: 0.75rem 0;
list-style: none;
}
details.faq-item summary::marker { display: none; }
details.faq-item[open] summary { color: var(--accent); }
The <details> element is interactive, fully keyboard navigable, and requires zero JavaScript.
CSS-Only Dark Mode
:root {
color-scheme: light dark;
--bg: #ffffff;
--text: #111111;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #111111;
--text: #f0f0f0;
}
}
body {
background: var(--bg);
color: var(--text);
}
No localStorage, no script, no flash of unstyled content — the browser applies the correct scheme before rendering.
When to Accept a JavaScript Dependency
Zero-JS is appropriate for:
- Informational publications and blogs
- Marketing landing pages
- Documentation sites
- Portfolio pages
JavaScript is genuinely required for:
- Real-time data (WebSocket feeds, live pricing)
- Client-side state management (shopping cart, authentication tokens)
- Complex form workflows (multi-step wizards, file uploads)
- Maps, charts, and data visualisations
Performance Impact
A typical React SPA ships 150–400 KB of JavaScript before your application code. A zero-JS Astro page ships 0 bytes of JavaScript by default. On a 4G mobile connection, parsing a 300 KB JS bundle takes roughly 300–1000 ms depending on the device CPU.
For content-first sites, zero-JS pages consistently score 100/100 in Lighthouse Performance audits.
Building Zero-JS Pages in Astro
Astro is zero-JS by default. Every .astro component renders to static HTML unless you explicitly add a client directive:
---
// This renders to pure HTML — no JavaScript sent to browser
const title = "Hello";
---
<h1>{title}</h1>
<!-- Only hydrate this component when it enters the viewport -->
<InteractiveChart client:visible />
Remove client:* directives to return any component to zero-JS output.
Written by Editorial Team
Tech contributor covering software architecture, AI research, cloud infrastructure, and systems engineering practices.