Why Your Next.js Static Blog Still Ships JavaScript
A Next.js blog of mostly static articles still gets flagged by Lighthouse for the JavaScript it ships. Where is that code coming from, and do you have to leave Next.js to cut it?

- Next.js static exports include JavaScript alongside HTML and CSS.
- A developer’s successful move to Hono reflects the needs of a largely noninteractive blog.
- Before migrating, reduce client boundaries and unnecessary scripts, then measure under consistent conditions.
Static export is not a JavaScript removal switch
With output: 'export', Next.js builds assets that a static web server can host. Those assets include JavaScript. The official export guide explains that App Router Server Components execute during the build, producing initial HTML and a payload for navigation between routes.
Interactive Client Components still need browser code. Hydration attaches behavior to their prerendered HTML. Avoiding per-request HTML generation and avoiding client execution are two different goals, which is why a static blog can still have a meaningful script budget.
One developer removed features the blog did not need
A Bloffy developer’s account, circulating on Hacker News on October 26, describes reducing the browser runtime on a largely noninteractive blog.
The developer ultimately chose Hono, retaining JSX while moving away from features the blog was unlikely to need. The reported result was 100 across four Lighthouse categories. Its practical question is whether the delivered behavior earns its cost on a page built mainly for reading.
Shrink client boundaries before rebuilding the site
Next.js provides a less disruptive starting point. Its component guidance recommends placing 'use client' on the interactive parts rather than broad sections of UI. A search box can be a Client Component while its surrounding layout remains server-rendered.
| Source of browser work | Possible change |
|---|---|
| A small interactive control creates a large client boundary | Move that boundary to the control’s component |
| A page-specific external tool loads sitewide | Scope its script to the relevant page or layout |
| A nonessential script runs early | Choose a loading strategy appropriate to its function |
The script guide distinguishes root-layout scripts from scripts scoped to particular routes. It also offers lazyOnload for loading during browser idle time. Delaying a script does not remove it, but can change when its work occurs.
Deleting script tags from generated HTML is not equivalent to preserving functionality while reducing its cost. Keep checking the controls and navigation people actually use as you make those changes.
A mostly static page can isolate its interactive widgets
If the content is static and only a few widgets need browser behavior, Astro’s islands model offers a different default. Components render to HTML and CSS, with client JavaScript enabled explicitly through client:* directives. A heavier widget farther down the page can use client:visible to load when it enters view.
Adding third-party tools changes the final page regardless of framework. And Lighthouse scores vary with devices, ads, routing and browser extensions.
List the interactions your article pages need, reduce unnecessary code, and compare the results under the same conditions. If little functionality remains to justify the runtime, an HTML-first migration becomes a concrete trade-off to assess.