I thought I would share a rant regarding JavaScript usage on modern websites.
To clarify, this discussion focuses primarily on content sites rather than complex web applications requiring heavy client side interactivity.
In recent years, frontend developers frequently chased shiny new tools without pausing to evaluate necessity. Building websites now routinely involves an endless list of dependencies, a node_modules directory large enough to form a black hole, and countless supply chain vulnerabilities. Standard websites frequently consume over 500 megabytes of RAM in a single browser tab. We have thoroughly over-engineered the web.
Why did we start using JavaScript and React to generate simple HTML in the first place? Perhaps because it felt convenient at the time.
Frontend Libraries
Frontend libraries and metaframeworks empower developers to build anything from a static marketing page to a massive enterprise application. However, we often fell into the trap of applying heavy over-engineering to simple web projects. Frontend libraries are crucial for large applications, but completely unnecessary for smaller websites.
I used to love NextJS, but much of its overhead felt redundant for standard publishing needs. It simplified building fast experiences, server-generating JavaScript, and leveraging features like page link prefetching on hover. Yet we have successfully generated HTML on the server for over thirty years. Did we really need to reinvent that foundation?
What I am Building
In recent projects, I took a step back to earlier days of web development before everything became overly complicated. I discovered Datastar a while ago, and it fundamentally changed my workflow. Think of it as using the server to generate UI elements, utilizing server-sent events, client-side signals, and lightweight interactivity. I now build websites containing perhaps 10-20kb of JavaScript in total while requiring no compiler step. The performance is great, the API remains simple, and dependency tracking risks are gone since there are no external packages to manage.
My transition toward lightweight websites began when AstroJS first came on the scene. The philosophy of shipping zero JavaScript by default for static HTML was refreshing to see again. Fast forward a couple of years, and I needed to build an interactive website with server-driven content and chose Astro. To solve this, I built a Datastar plugin for AstroJS, which proved really useful and I published it on NPM.
Several examples are live om Datastar Astro project: https://astro-datastar.wrux-6a1.workers.dev/examples/. Feel free to inspect the network tab while testing them and to get an idea of how Datastar works.
I am currently build a project that uses a Cloudflare worker running Rust and WebAssembly to generate pages. It operates as a streamlined backend setup that reads from a CMS, handles caching, and outputs pages very efficiently. Datastar has a native Rust integration that performs exceptionally fast inside workers compiling to WebAssembly. This architectural shift allowed me to drop Vercel, which frequently hit resource limits, and migrate to Cloudflare for free up to 100,000 monthly page views while getting much better TTFB on webpages.
Consequently, I can now deliver an interactive website that generates pages in under 10ms while sending only 16 kilobytes of JavaScript down to the client. I also dropped Tailwind entirely and built a custom design system, though that is a topic for another rant. With Brotli compression enabled, the total asset weight sent to the client is nearly negligible.
Let's Use More Browser APIs
The web landscape evolved significantly, and modern browsers improve continuously. It is time to return to building simple websites by relying more heavily on native web standards.
Implementing lazy-loading images once required custom JavaScript solutions, but today it is handled natively via a single loading="lazy" attribute. Creating accessible dialog elements used to involve complex workarounds, yet we now possess the native <dialog> element and a straightforward API.
NextJS and Astro gained popularity partly by offering useful utility tooling, such as pre-loading subsequent pages to create an instant perceived performance boost on click. This capability has already arrived in browsers as a native standard via the Speculation Rules API.
Below is an example code snippet implementing the Speculation Rules API to instruct the browser which links to prefetch on hover. This is supported in Chromium based browsers, highlighting how native browser implementations are replacing features once locked inside proprietary metaframeworks.
<script type="speculationrules">
{
"prefetch": [
{
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": { "href_matches": "/api/*" } }
]
},
"eagerness": "moderate"
}
]
}
</script>
Minimising Analytics Overhead
Every developer knows the frustration of putting immense effort into building a lean content website with pristine performance metrics, only for marketing teams to then request 500kb of tracking scripts.
Managing this tension is always challenging. I have experimented with Plausible and similar privacy-focused alternatives, though marketing managers sometimes find them restricted in certain reporting dimensions.
Many stakeholders still expect traditional platforms like Google Analytics by default. If anyone has practical insights on how to maintain robust tracking without bloating client-side JavaScript payloads, I would love to hear your approach.

Top comments (0)