DeadYet

One Worker, three stores, and a human in the loop.

DeadYet is a single Cloudflare Worker that renders its own HTML. D1 holds the people, R2 holds the photos, KV holds the caches. Nothing decides that somebody has died without a person looking at the evidence.

Visit deadyet.fyi

Server-rendered, no framework

Every page is HTML built from template strings in the Worker and sent in one response. There is no client-side framework and almost no client JavaScript: a few lines for search, the pools form, and the confetti. The pages are fast on a phone because there is nothing for the phone to do.

One codebase, one deploy, and the same Worker serves the public site, the account pages and the admin area, with the admin role checked on every request.

A DeadYet person page on a phone: the question, the photo, a large NO
A person page on a phone: one HTML response, no hydration.

D1, R2 and KV

People, statuses, categories, watches, pools, badges and accounts live in a D1 database with a single checked-in schema. Photos come from Wikimedia Commons, looked up by the person’s Wikidata ID, and are stored in an R2 bucket served from its own photo hostname, with the licence and credit kept alongside. KV holds page caches and the per-IP counters behind the rate limits: ten requests a minute on sign-in, sixty on lookups.

Rate limiting, caching and the photo pipeline are all platform primitives. There is no queue server, no image CDN subscription, and no database to patch.

A row of skulls, one circled in green. Keeping tabs on the famous.
Keeping tabs on the famous: the wall-of-faces house ad.

Nightly checks, human verdicts

Two cron jobs run every night. The sweep asks Wikidata whether any tracked person has gained a date of death, then looks for corroboration in the New York Times and Guardian APIs. A hit never changes a status on its own: it raises a flag in the admin review queue, where a person reads the sources and decides.

The same queue handles reports from visitors, suggestions for new people, and proposed edits. An optional Populate button in the admin area asks Claude, through Cloudflare AI Gateway, to draft a new person’s details for review. That is the only AI call in the site, and it is off by default.

Accounts and abuse

Authentication is better-auth on D1: passwords, Google, GitHub and Discord, TOTP second factors and passkeys. Registration is gated by Cloudflare Turnstile. Email verification is required before an email can receive Death Watch alerts, and web push subscriptions are stored per device.

Tests in the real runtime

More than 1,500 tests run inside workerd, the same runtime that serves production, with a fresh D1 database per test file. Continuous integration runs the suite and a dry-run deploy on a self-hosted runner on a Mac. Merges to the main branch deploy to a dev hostname; production deploys from a release.

The marketing images, including every house ad on this page, are generated by a script in the repo, so a copy change is a pull request, not a design ticket.

  • Three verdicts: YES, NO, UNKNOWN

    Three verdicts

  • A terminal-styled DeadYet ad

    Terminal

  • A Death Pools ad

    Death Pools

  • A coffee-themed DeadYet ad

    Coffee

By the numbers

1
Worker, no framework
1,500+
tests, run inside workerd
1,200+
commits
2
nightly status checks