A packed binary opened the system browser, so it felt like a tab, not
an app. Build with -tags webview (cgo) and the viewer instead opens the
site in its own window backed by the OS WebView: WKWebView on macOS,
WebView2 on Windows, WebKitGTK on Linux.
The viewer package picks an implementation at build time. The default
file opens the browser and keeps the build pure Go, so CGO_ENABLED=0 and
the release pipeline are untouched. The webview file links the platform
WebView and runs its event loop on the main goroutine, which main now
pins with LockOSThread before anything else, since macOS requires UI on
the initial thread. Both kage open and the embedded viewer serve over
HTTP in a goroutine and hand the URL to the viewer, then tear the server
down when the window closes or Ctrl-C cancels.
The window title comes from the archive's M/Title. OpenInBrowser moves
out of pack into the viewer package, its only caller.
Four commands: clone fetches a site into an offline folder, serve previews
one, pack collapses a mirror into a single file, and open serves a packed
file. Run kage <command> --help for the canonical, up-to-date list.
kage clone
kage clone <url> [flags]
Renders each page in headless Chrome, strips all JavaScript, localises CSS,
images, and fonts, and writes a browsable mirror to <out>/<host>/.
Output
Flag
Default
Meaning
-o, --out
$HOME/data/kage
Output root; the mirror lands in <out>/<host>/
--reserved
_kage
Reserved directory name for assets and crawl state
-f, --force
false
Delete any existing mirror for the host before crawling
--refresh
false
Re-render every page in place to pull in changed content
--no-resume
false
Do not read or write resume state
Scope
Flag
Default
Meaning
-p, --max-pages
0
Stop after N pages (0 = unlimited)
-d, --max-depth
0
Link-follow depth cap (0 = unlimited)
--scope-prefix
Only crawl pages whose path starts with this prefix
--subdomains
false
Treat subdomains of the seed host as in scope
--exclude
Path prefixes to skip (repeatable)
--traversal
bfs
Frontier order: bfs or dfs
Politeness
Flag
Default
Meaning
--no-robots
false
Ignore robots.txt
--no-sitemap
false
Do not seed URLs from sitemap.xml
--user-agent
Chrome UA
User-Agent for asset and robots fetches
Rendering
Flag
Default
Meaning
--scroll
false
Auto-scroll each page to trigger lazy loading
--settle
1.5s
Network-idle quiet period before snapshotting the DOM
--render-timeout
30s
Hard cap per page render
--headful
false
Run Chrome with a visible window (debugging)
--chrome
Path to the Chrome/Chromium binary
--control-url
Attach to an existing Chrome DevTools endpoint
--keep-noscript
false
Unwrap <noscript> content instead of dropping it
Concurrency and limits
Flag
Default
Meaning
--workers
4
Concurrent page render workers
--asset-workers
8
Concurrent asset download workers
--browser-pages
4
Chrome page-pool size
--max-asset-mb
25
Skip assets larger than N MB
--timeout
30s
Per-request timeout
-q, --quiet
false
Suppress per-page progress lines
kage serve
kage serve [dir] [flags]
Runs a local static file server over a cloned folder. With no dir, serves the
current directory.
Flag
Default
Meaning
-a, --addr
127.0.0.1:8800
Address to listen on
kage pack
kage pack <mirror-dir> [flags]
Packs a cloned mirror into one distributable file: an open ZIM archive, or a
self-contained executable that serves the site offline when run. A bare host name
is resolved against the default output directory, so kage pack example.com
works right after kage clone example.com.
Flag
Default
Meaning
--format
zim
Output format: zim or binary
-o, --out
per format
Output path; <host>.zim for zim, <host> (or <host>.exe) for binary
--base
this kage
Base kage binary to append to (--format binary); point at another platform's binary to build a viewer for it
--no-compress
false
Store every cluster raw, no zstd
--title
main page <title>
Archive title
--description
Archive description
--language
eng
Archive language code
--date
today
Archive date (YYYY-MM-DD); pass a fixed value for a reproducible file
kage open
kage open <file.zim> [flags]
Serves a packed ZIM over a local HTTP server for offline reading, the read side
of kage pack --format zim.
Flag
Default
Meaning
-a, --addr
127.0.0.1:8800
Address to listen on
--open
true
Open the default browser (--open=false to skip)
Built with -tags webview (which needs cgo), kage open shows the archive in a
native window instead of the browser, and --open no longer applies. The default
CGO_ENABLED=0 build uses the browser.