Ever Run Into These Problems?

You bookmark a great article, come back months later — blank page, infinite loading spinner, or the whole thing freezes because some long-dead analytics server can't be reached. That page was never really yours. It was just a thin client for someone else's JavaScript.

Another scenario: you need to read a documentation site offline — on a plane, in the field, or in some server room. Or maybe you want to permanently archive a website before it disappears one day.

That's exactly what kage (Japanese for "shadow", pronounced /ka-ge/) was built to solve.


What Is kage?

kage is an open-source command-line tool written in Go. It renders pages with headless Chrome, waits for everything to load, captures a DOM snapshot, then removes all JavaScript and downloads CSS, images, fonts, and other static assets locally. What you get is a collection of .html files you can open directly from disk — no network needed, no scripts executed.

  • GitHub Stars: 2600+ (created June 2026, growing fast)
  • 🏷️ Language: Go
  • 📜 License: MIT
  • 🧑‍💻 Author: tamnd

kage vs. Traditional "Save As"

Feature Browser "Save As" wget / curl kage
JavaScript rendering ✅ Full headless Chrome rendering
Auto JS stripping ✅ Completely removes all scripts
SPA/dynamic content ✅ Works with Vue/React/Angular pages
Full-site cloning ⚠️ Limited ✅ Follows links automatically, breadth-first crawl
Package as single file ✅ ZIM / self-contained executable
Offline ready ⚠️ Often broken ⚠️ Often broken ✅ Perfect offline experience

How It Works Under the Hood

Visit URL → headless Chrome renders → Wait for page to stabilize → Capture final DOM → Remove all <script> tags → Download CSS/images/fonts → Save locally → Follow links

kage doesn't just download raw HTML source. It renders the page like a real browser would, making sure what gets saved is exactly what you see with your own eyes.


Installing kage

kage supports multiple installation methods across Linux, macOS, and Windows.

Method 1: Via Go

If you have Go installed (1.21+ recommended):

go install github.com/tamnd/kage/cmd/kage@latest

Method 2: Via Homebrew (macOS)

brew install --cask tamnd/tap/kage

Method 3: Via Scoop (Windows)

scoop bucket add tamnd https://github.com/tamnd/scoop-bucket
scoop install kage

Method 4: Via apt (Ubuntu/Debian)

# Add the repo key and source
curl -fsSL https://tamnd.github.io/linux-repo/gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/tamnd.gpg
echo "deb [signed-by=/usr/share/keyrings/tamnd.gpg] https://tamnd.github.io/linux-repo/apt stable main" | sudo tee /etc/apt/sources.list.d/tamnd.list
sudo apt update && sudo apt install kage

Method 5: Via dnf (Fedora/RHEL)

sudo dnf config-manager --add-repo https://tamnd.github.io/linux-repo/dnf/tamnd.repo
sudo dnf install kage

Method 6: Via Docker (No Chrome Install Needed)

The Docker image comes with Chromium built in:

docker run --rm -v "$PWD/out:/out" ghcr.io/tamnd/kage clone paulgraham.com

Verify Installation

kage --version
kage completion bash  # or zsh / fish — enables tab completion

Note: kage requires Chrome or Chromium. Unless you're using Docker, you'll need Chrome/Chromium installed on your host. kage auto-detects system installations, or you can specify the path with --chrome or the KAGE_CHROME environment variable.


Quick Start: Clone a Website in 3 Minutes

Let's clone Paul Graham's blog as an example:

# 1. Clone the entire site to $HOME/data/kage/paulgraham.com/
kage clone paulgraham.com

# 2. Preview locally
kage serve $HOME/data/kage/paulgraham.com
# Open http://127.0.0.1:8800 in your browser

That's it! All articles, images, and stylesheets are frozen on your disk — zero network dependency.

Limiting the Scope

If you just want a quick test run, limit the clone depth:

# Only clone the first 50 pages, follow links up to 2 levels deep
kage clone paulgraham.com --max-pages 50 --max-depth 2

# Only clone a specific subdirectory
kage clone go.dev --scope-prefix /doc

# Skip certain paths (exclude ads or irrelevant pages)
kage clone example.com --exclude /ads --exclude /track

Useful Options Cheat Sheet

Option Default Description
-o, --out $HOME/data/kage Output root directory
-p, --max-pages 0 (unlimited) Maximum pages to clone
-d, --max-depth 0 (unlimited) Link-following depth
--scope-prefix None Only clone paths starting with this prefix
--subdomains false Include subdomains
--scroll false Auto-scroll pages (triggers lazy loading)
--workers 4 Number of concurrent page renders
--no-robots false Ignore robots.txt
--refresh false Incremental update of existing clone

Advanced Features

1. Auto-Scroll for Lazy Loading

Many modern sites use lazy loading for images — they won't load unless you scroll. kage handles this:

kage clone example.com --scroll

This makes kage scroll each page all the way to the bottom, ensuring all lazy-loaded images, iframes, and other content get fully rendered and saved.

2. Incremental Updates (--refresh)

Your cloned blog got new posts last month? No need to start over:

kage clone paulgraham.com --refresh

--refresh re-renders existing pages and grabs new content. kage's cloning is idempotent: the same page — whether accessed via http or https — is only saved once.

3. Graceful Interruption & Resume

Hit Ctrl+C mid-clone? No problem — kage saves your progress automatically:

# Press Ctrl+C to interrupt; next run picks up where it left off
kage clone paulgraham.com

4. Include Subdomains

kage clone example.com --subdomains

This also clones blog.example.com, docs.example.com, and other subdomains.


Packaging: From Folder to Single File

After cloning, you have a folder with thousands of small files. Copying it around is slow. kage can compress the entire mirror into a single file.

Option 1: Package as ZIM File

ZIM is an open offline format used by the Kiwix project, designed for long-term archiving:

# Package
kage pack paulgraham.com               # Generates paulgraham.com.zim

# Read
kage open paulgraham.com.zim           # Preview locally

# Or serve with Kiwix
kiwix-serve paulgraham.com.zim         # HTTP server

Why ZIM? It's an open standard. A .zim file you create today with kage can still be opened by any Kiwix reader ten years from now. It uses zstd compression — text is highly compressed, images and media are stored as-is.

Option 2: Package as Standalone Executable

This is kage's coolest feature — one executable = an entire website:

# Package as a self-contained binary
kage pack paulgraham.com --format binary -o paulgraham

# Run it directly, zero dependencies
./paulgraham
# Automatically starts an HTTP server — just open it in your browser

Anyone who receives this file doesn't need to install anything: no kage, no browser, no ZIM reader. Just run it and get the full offline website.

The binary is roughly 13 MiB (kage itself) + the website content size.

Cross-Platform Packaging

You can package for Windows from macOS:

# Generate a Windows executable on Mac
kage pack paulgraham.com --format binary \
  --base kage-windows-amd64.exe
# Outputs paulgraham.exe

Just download the kage binary for the target platform from the releases page and use it as --base.

Option 3: Double-Click Desktop App

Add the --app flag and kage generates a desktop app with an icon:

# macOS → .app bundle
kage pack paulgraham.com --app
open paulgraham.app

# Linux → AppImage
kage pack paulgraham.com --app --base kage-linux-amd64
# Outputs paulgraham.AppDir / paulgraham.AppImage

Double-click to open — no terminal window, straight into the website.


Real-World Use Cases

Use Case 1: Save a Tech Blog as an Offline Knowledge Base

# Clone all of Paul Graham's essays
kage clone paulgraham.com --scroll -o ~/docs/paulgraham

# Package as ZIM, read on Kindle or phone anytime
kage pack paulgraham.com

# Or package as a single file to share with friends
kage pack paulgraham.com --format binary -o ~/share/paulgraham-essays

Use Case 2: Offline Documentation Sites

# Clone the official Go docs
kage clone go.dev --scope-prefix /doc --max-depth 3

# On a business trip with no Wi-Fi? Just serve locally
kage serve ~/data/kage/go.dev

Use Case 3: Long-Term Archiving

Some websites might shut down or migrate. Use kage to archive regularly:

# Add to cron, auto-update monthly
# 0 2 1 * * kage clone example.com --refresh

Things to Keep in Mind

  1. robots.txt: kage respects robots.txt by default. Use --no-robots if you need to bypass it in dev/test environments.
  2. Chrome dependency: Chrome/Chromium is required on the host (except with Docker).
  3. Disk space: Large sites can take up several GB after cloning.
  4. Legality: Respect website copyrights and robots.txt. Don't use it for commercial purposes or to infringe on copyrighted content.

Summary

kage is the most elegant website offline cloning tool available today. It renders pages with headless Chrome, strips all JavaScript, and turns dynamic web pages into static HTML that truly belongs to you. ZIM packaging and self-contained executables make it a perfect solution for long-term archiving and distribution.

If you often need to read docs offline or want to permanently preserve website content, kage absolutely deserves a spot in your toolbox.