A new tool that clones websites into offline, script-free archives reflects a growing unease about web bloat and JavaScript dependency.
There's a quiet counter-movement forming in web development circles. It's not loud, not revolutionary, not a framework war. It's simpler than that: developers are building tools to strip JavaScript out of websites entirely.
https://github.com/tamnd/kage is the latest expression of this impulse. The tool clones any website into a folder you can browse offline, with every script removed. Real headless Chrome renders each page, waits for it to settle, snapshots the DOM as a human would see it, then deletes all the JavaScript and pulls CSS, images, and fonts to local paths. What remains looks like the live site but runs no code.
The name means "shadow" in Japanese, and it's apt. kage creates a ghost of a website, preserving its appearance while exorcising its behavior.

The Pattern: Save As Is Broken
The problem kage addresses is one most developers have encountered but rarely articulated. You hit "Save As" on a page you want to keep. Six months later, you open it to find a blank screen, a spinner that never stops, or a copy that still tries to phone home to an analytics server that no longer exists. The page was never really yours. It was a thin client for someone else's JavaScript.
This isn't a new complaint, but the tools to address it are getting more sophisticated. kage builds on concepts from wget, httrack, and various single-page app archivers, but adds a crucial layer: it uses a real browser to render the page first, capturing the DOM state that JavaScript actually produces rather than just fetching raw HTML.
The technical approach matters here. By driving Chrome, kage can handle lazy-loaded images, dynamic content that appears after initial load, and sites that require JavaScript to render their basic structure. Then it rips that JavaScript out, leaving behind only the visual result.
Evidence of Adoption Signals
The project has already found its audience among specific developer demographics. The GitHub repository shows activity, and the documentation is unusually thorough for a tool of this scope. It supports multiple output formats: a browsable folder structure, ZIM archives (the format behind Kiwix, used for offline Wikipedia), and self-contained executables.
That last option is particularly interesting. You can pack paulgraham.com into a single binary that serves the site offline when run. Whoever receives it needs nothing installed, not kage, not a ZIM reader, nothing. The trade-off is size (the binary carries a whole kage, so it weighs around 13 MiB plus the site content), but for certain use cases, that's acceptable.
The ZIM format support connects kage to a broader ecosystem. Kiwix users carry Wikipedia, Stack Overflow, and Project Gutenberg onto boats, into classrooms with no internet, and onto phones for long flights. kage's output plugs directly into that world, though without full-text search indexing.

The Webview Option
One feature suggests where this kind of tool might be heading. Build kage with the webview tag, and it opens sites in native windows instead of browser tabs. WKWebView on macOS, WebView2 on Windows, WebKitGTK on Linux. Paul Graham's essays, offline, in something that looks and feels like a real app.
This bridges a strange gap in how we think about web content. We treat websites as inherently ephemeral, tied to their hosting infrastructure. But much web content is effectively static text with decorative JavaScript. kage makes that content portable in ways that feel almost old-fashioned, like distributing software the way we used to before everything moved to the cloud.
Counter-Perspectives: Why This Might Not Matter
There are reasonable objections to this approach.
First, most websites are not static documents. They're applications. Stripping JavaScript from Gmail or Figma or Notion doesn't give you a useful offline version; it gives you a broken shell. kage works best on content sites, blogs, documentation, and reference material. The web it's archiving is increasingly not the web most people use.
Second, there's a philosophical question about whether websites should be archivable at all. Publishers might not want their content frozen in time, stripped of tracking, divorced from their analytics. The tool explicitly ignores robots.txt by default (though you can opt into respecting it), and its existence challenges assumptions about how content should be distributed and consumed.
Third, the technical complexity is significant. kage needs a real Chrome installation, which limits where it runs. The container image bundles Chromium to solve this, but that's a heavy dependency for what's conceptually a simple operation: save this webpage.
The Broader Pattern
kage fits into a larger trend of developers building tools to reclaim control over their digital environment. It shares DNA with ad blockers, reader modes, and the broader "slow web" movement. It reflects a discomfort with the state of web development, where simple content often requires megabytes of JavaScript to display.
Whether this discomfort translates into lasting change or remains a niche concern depends on what happens next. The web's JavaScript dependency has deepened over the past decade, not lessened. Every new framework adds another layer. Every new feature requires another bundle.
But tools like kage suggest that at least some developers are looking for exits. Not from the web itself, but from its current implementation. The question is whether offline archiving is a practical solution or a philosophical statement.
How It Works Under the Hood
The architecture is straightforward. A pool of Chrome tabs renders pages while a separate pool fetches assets over plain HTTP. Every URL maps deterministically to a local path, so links get rewritten before the asset they point at has even finished downloading.
The crawl respects basic constraints: breadth-first, robots.txt compliant (by default), seeded from sitemap.xml, idempotent by file path. Hit Ctrl-C and it saves its state on the way out; run it again and it picks up where it stopped.
The output structure is predictable:

Comments
Please log in or register to join the discussion