Reference
A working example
examples/vanilla-js is a complete round trip with no build step: a Node
http server that receives and validates a report using bugbottle/server,
and a plain HTML form that captures a screenshot and posts it.
cd examples/vanilla-js
npm install
node server.mjsOpen http://localhost:8787, write a message, send, and watch the server print the validated report.
examples/inbox is the next step: the same round trip, but the reports stay.
A dependency-free Node server that receives them with handleReport, writes
each one to disk as JSON beside its PNG, and serves a read-only inbox — a
list, a detail page with the rendered Markdown and the picture, copy as
Markdown, delete — behind one password from INBOX_PASSWORD, which it refuses
to start without. Small enough to run one per client site on a €4 VPS behind
Caddy, and honest about being an example rather than a product: no accounts,
no search, no assignment.
npm run build
INBOX_PASSWORD=$(openssl rand -base64 24) node examples/inbox/server.mjsIt ships with a Dockerfile, a compose.yml and a Caddyfile, so putting one
on a VPS is docker compose up and a domain; its README walks through Dokploy
in eight lines. Reports land on a named volume, the image runs as a non-root
user and installs nothing, and GET /health is public for the platform's
check. GET /metrics is behind the password with everything else and answers
in OpenMetrics text — one counter per onDecision reason, how many reports are
on disk, and when the newest arrived — so Prometheus can alert on an endpoint
that has quietly stopped receiving.
Read examples/inbox/README.md before you put one on the internet — the
screenshots are on disk, so the disk is the bucket the privacy section above
is about.