A Cloudflare Worker that serves static websites stored as .tar.gz archives in KV. Users upload tarballs to the ASSETS_KV namespace and the worker serves individual files from them on demand, streaming and decompressing the archive at the edge.
Tarballs are stored in ASSETS_KV under the key <username>/<asset>. The worker exposes two routes:
GET /— lists all entries inASSETS_KVas a simple HTML index with links to each asset's preview URL.GET /preview/:username/:asset/:filepath— retrieves the tarball forusername/assetfrom KV, decompresses it via aDecompressionStream, and streams through the tar entries usingstreaming-tarballuntil it finds the requestedfilepath. The responseContent-Typeis inferred from the file extension usingmime. Returns404if the tarball or the file within it cannot be found.
The entire worker is defined here using Hono as the router.
| Import | Purpose |
|---|---|
hono |
Lightweight router for Cloudflare Workers |
streaming-tarball |
Streams and extracts entries from a tar archive without buffering the whole file |
mime |
Maps file extensions to MIME types |
The Hono app is typed with { Bindings: Env } where Env is generated from wrangler.jsonc by running wrangler types (see worker-configuration.d.ts).
Assets are .tar.gz files uploaded to ASSETS_KV under the key <username>/<bundle-name>, for example acarroll/bundle.tar.gz.
The tarball must have no root directory — files should sit at the top level inside the archive:
index.html
style.css
script.js
Not:
bundle/
index.html
style.css
Upload with wrangler:
npx wrangler kv key put --binding=ASSETS_KV "acarroll/bundle.tar.gz" --path=./bundle.tar.gzOnce uploaded, files are accessible at:
/preview/<username>/<bundle-name>/<filepath>
For example, given the key acarroll/bundle.tar.gz and a tarball containing index.html and images/hero.png:
| File | URL |
|---|---|
index.html |
/preview/acarroll/bundle.tar.gz/index.html |
images/hero.png |
/preview/acarroll/bundle.tar.gz/images/hero.png |
If filepath is omitted it defaults to index.html.
npm run dev # local dev server via wrangler
npm run deploy # deploy to Cloudflare
npm run cf-typegen # regenerate types from wrangler.jsonc
npm test # run testsThe worker expects a KV namespace bound as ASSETS_KV. Create one and update wrangler.jsonc with the namespace ID:
npx wrangler kv namespace create ASSETS_KV