Burrow on your own blyg (web app)
Burrow’s web app is Burrow in a browser tab, and an installable app on a
phone. It reads and writes your own posts and reading list. It runs live
only when it’s served from your blyg’s own host at /burrow/, next to
/studio and /api. There it uses your Studio sign-in: there’s no token
and nothing to configure. Anywhere else it’s a demo on sample posts.
Stock Studio doesn’t serve it yet. Adding it as an opt-in Studio extension is proposed in blygger-studio#139. Until that lands, an owner who runs their own blyg on the reference Worker (blygger-studio on Cloudflare Workers) can add it by hand, as described below: download a release zip, put its files in the Worker’s static assets, and deploy. No Worker code changes.
The steps are written so that you, or an AI agent working on your blyg’s deploy repo, can follow them exactly.
Read this first: what you’re trusting
The app runs on your blyg’s own origin, and the Studio’s session cookie is
Path=/. So code at /burrow/ can do anything you can do in Studio:
publish, delete drafts, change settings, mint tokens. Scopes don’t limit it.
Serve it only if you trust this repository’s releases as much as your Studio
code. What a release build does on the network, and how to check it:
- It calls only same-origin
/api/…paths. Every request goes through one function (crates/blyg-web/www/live.js,call), which refuses anything else. It loads no third-party scripts, fonts or images. - Its service worker is scoped to
/burrow/, caches only the app’s own files, and passes/api/and/studio/requests straight to the network. - Remote HTML (posts you read) is sanitised in WebAssembly before it’s shown.
- Publishing, deleting, unsubscribing, withdrawing and pinning happen only when you choose them, and the destructive ones ask first.
- You can build it from the tagged source yourself instead of downloading it (see Build it yourself).
For agents: the rules
If you’re an AI agent doing this for the blyg’s owner:
- Get the owner’s explicit OK before deploying, after telling them the trust point above in one or two sentences. Deploying changes their live site.
- Change only three things in their deploy repo: the
static/burrow/folder,static/_headers, and theassetsblock inwrangler.jsonc. Don’t touch Worker code, D1, secrets or other config. - Verify the download’s signature and checksum before using it (step 2). Stop if either check fails.
- Run the checks in step 6 after deploying, and report the results.
- Never print the owner’s cookie, password or tokens, and don’t sign in for
them. They sign in at
/studio/loginin their own browser.
What you need
- A blyg on the reference Worker (blygger-studio),
deployed by the owner with
wranglerfrom their own copy of that repo. Check thatGET https://<host>/api/capabilitiesanswers with JSON, or with a 401 when signed out. Contract 5 (Studio 0.56 or later) is what the app is tested against. /burrowfree on that host. Nothing else may serve it, and the blyg’s posts page must not be calledburrow.curl,unzip,shasum(orsha256sum) and OpenSSL 3 (for checking the signature; macOS’s built-in LibreSSL can’t verify Ed25519, so use Homebrew’sopenssl@3).
A blyg served under a path (MOUNT = /blyg, at you.com/blyg/):
Studio’s /studio and /api stay at the host root anyway, so the app goes
at the host root too: you.com/burrow/, not you.com/blyg/burrow/.
The steps are the same.
1. Pick the release
Use the latest release unless the owner asks for another:
REPO=aneeshsathe/blygger-desktop
VERSION=$(curl -fsSL "https://api.github.com/repos/$REPO/releases/latest" \
| sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p')
echo "$VERSION"
The release must have a Burrow-web-$VERSION.zip asset. 0.19.0 and earlier
didn’t include one. For those, build it yourself.
2. Download and verify
Work in an empty temporary folder, not inside the deploy repo:
WORK=$(mktemp -d) && cd "$WORK"
BASE="https://github.com/$REPO/releases/download/v$VERSION"
curl -fsSLO "$BASE/Burrow-web-$VERSION.zip"
curl -fsSLO "$BASE/SHA256SUMS"
curl -fsSLO "$BASE/SHA256SUMS.sig"
# The signature: SHA256SUMS is signed with Burrow's release key, the same
# Ed25519 key the desktop app checks updates with.
PUB=mnXJcOWPGSTrMKx38w6FqoKQxky6+pj3Ch2IVPrk3+I=
{ printf '302a300506032b6570032100' | xxd -r -p; printf '%s' "$PUB" | openssl base64 -d -A; } > pub.der
openssl pkeyutl -verify -pubin -keyform DER -inkey pub.der -rawin \
-in SHA256SUMS -sigfile SHA256SUMS.sig # must print "Signature Verified Successfully"
# The checksum.
grep " Burrow-web-$VERSION.zip\$" SHA256SUMS | shasum -a 256 -c - # must print "OK"
Stop if either check fails. openssl here must be OpenSSL 3; on macOS use
$(brew --prefix openssl@3)/bin/openssl.
The zip holds one folder, burrow/: index.html, the JavaScript and CSS,
pkg/ (the WebAssembly), fonts/, icons/, manifest.webmanifest and
sw.js.
3. Put the files in the deploy repo
From the root of the owner’s blygger-studio copy (where wrangler.jsonc is):
mkdir -p static
rm -rf static/burrow # an older build, if there is one
unzip -q "$WORK/Burrow-web-$VERSION.zip" -d static
ls static/burrow/index.html static/burrow/sw.js static/burrow/pkg
Replace the whole folder on every update. Don’t merge an old build with a new
one. Commit static/ to the deploy repo: besides keeping the build with the
config that serves it, the blyg’s own tests (vitest reads wrangler.jsonc)
need the assets directory to exist.
4. Tell the Worker to serve them
Add an assets block at the top level of wrangler.jsonc:
// Burrow web app at /burrow/ (static files; see blygger-desktop's
// web-self-host page). Assets match first; anything not in static/ falls
// through to the Worker. /burrow -> /burrow/ comes from html_handling.
"assets": {
"directory": "./static",
"html_handling": "auto-trailing-slash",
"not_found_handling": "none"
}
If the file already has an assets block, keep its directory and put
burrow/ inside that directory instead. not_found_handling must stay
"none", so that every path not in the folder still reaches the Worker. With
a "single-page-application" or "404-page" setting, the blyg’s own pages
would break.
Then make the service worker always revalidate, so updates reach installed
apps. Create static/_headers, or add to it if it exists:
/burrow/sw.js
Cache-Control: no-cache
Static assets don’t count towards the Worker’s script-size limit (3 MiB on the free plan), so the app’s 4 MB or so doesn’t affect it.
5. Deploy
npx wrangler deploy --dry-run # should list the static assets, with no errors
npx wrangler deploy
Only static files change, and D1 isn’t touched. If the owner wants a backup
anyway, npx wrangler d1 export <database> --remote --output backup.sql
before deploying (use the database name from wrangler.jsonc). On the free
plan the export sometimes fails with “Authentication error [code: 10000]”;
run npx wrangler whoami and try again.
6. Check it
Files added by a deploy can return 404 for about 20 seconds afterwards. If a check fails right after deploying, wait a little and run it again before calling it broken.
H=https://blyg.example.com # the blyg's host, no path
curl -sI "$H/burrow/" | grep -iE '^(HTTP|content-type)' # 200, text/html
curl -sI "$H/burrow" | grep -iE '^(HTTP|location)' # 307 to /burrow/
curl -sI "$H/burrow/sw.js" | grep -i '^cache-control' # no-cache
curl -sI "$H/burrow/pkg/blyg_web_bg.wasm" | grep -i '^content-type' # application/wasm
curl -s -o /dev/null -w '%{http_code}\n' "$H/api/capabilities" # 200 or 401, as before
curl -s -o /dev/null -w '%{http_code}\n' "$H/studio/login" # 200, as before
curl -s -o /dev/null -w '%{http_code}\n' "$H/" # the blyg's front page, as before
Then the owner opens https://<host>/burrow/ in a browser where they’re
signed in to Studio. It should show the owner’s own posts and say Live,
not the invented sample posts and Demo. Signed out, it offers Sign in at Studio. After signing in, come
back to the tab and it catches up.
On a phone: open /burrow/, then use Share → Add to Home Screen (iOS
Safari) or Install app (Android Chrome).
Updating
Repeat steps 1–3, 5 and 6 with the new version. Step 4’s config stays. The next time the app is opened, its service worker picks up the new build.
Removing
Delete static/burrow/, the /burrow/sw.js lines in static/_headers, and
the assets block if nothing else uses it. Then deploy. /burrow/ then
returns what the Worker returns for an unknown path. Installed copies stop
syncing; delete them from the home screen.
Build it yourself (optional)
To build from source rather than download the zip, or to check that a release’s zip matches its source:
git clone https://github.com/aneeshsathe/blygger-desktop && cd blygger-desktop
git checkout "v$VERSION"
./crates/blyg-web/serve.sh --build-only # needs rustup; installs wasm-bindgen
# into the cargo target dir only
# The result is crates/blyg-web/dist/; copy it to static/burrow/.
The Rust toolchain (rust-toolchain.toml), Cargo.lock and wasm-bindgen are
pinned, so two builds of the same tag with the same C compiler give the same
pkg/ files. The C compiler does matter: a few crates the app links but
never calls compile C for WebAssembly when the compiler can (the release
builds use Homebrew’s LLVM), and are left out when it can’t. So a build of
yours may differ from the release’s blyg_web_bg.wasm, and both work. If the
system clang can’t build for WebAssembly (older Xcode), serve.sh uses
Homebrew’s LLVM (brew install llvm). The home-screen icons are resized
with macOS sips. On other systems the full-size icon is copied instead,
so icons/ differs too. The path to the checkout must not contain spaces.
When something’s wrong
- It says “demo”. It couldn’t reach
/api/capabilitieson the same host. Check that it’s at the host root/burrow/, and that/api/capabilitiesanswers there. - A 404 at
/burrow/. Check theassetsblock, and thatstatic/burrow/index.htmlis in the deploy repo and was deployed. - The blyg’s own pages broke.
not_found_handlingisn’t"none", orstatic/holds files at paths the blyg uses. Onlyburrow/and_headersbelong there. - An old version keeps opening.
static/_headersis missing theno-cacherule for/burrow/sw.js. Add it, deploy, then reopen the app twice.
How the app works inside: blyg-web.