I build small Chrome extensions under #DHSeaDev, and the newest one is a fan project: KH4 Companion, an unofficial countdown to Kingdom Hearts IV — days-left toolbar badge, series anniversary milestones, news and trailer feeds, a lore compendium in original prose, and a three-lane rhythm minigame called Keyblade Strike. It's packaged at 0.2.0 and the Chrome Web Store listing is in preparation. Three design problems turned out to be interesting.
The target is a window, not a date
Kingdom Hearts IV has no release date. It has a window — Late 2027 — and a countdown app that pretends otherwise is lying with a number. So the countdown carries two modes on its face: window mode, which counts to a conservative end-of-window anchor and says so in its label, and date mode, which activates only when a real announced date is entered in settings. The storage listener flips the toolbar badge the moment the setting changes. The dishonest version of this feature is one line shorter, and I wrote it first.
A countdown you can unit test
The countdown module never calls the clock. Time arrives as an argument — computeRemaining(nowMs, target) — and the module has no DOM, no chrome.*, and no fetch, so the same file runs in Node tests and in the extension unchanged. The service worker is relay-only: it holds no durable state, wakes on a six-hour alarm to re-render the badge text, and everything it knows it reads back out of storage. Milestones are the same shape — an annual month/day pair plus a pure next-occurrence function — so the anniversary list is testable across year boundaries without mocking anything.
Feeds without a backend
News and trailers come from public feeds — KHWiki, Reddit, Google News, YouTube — fetched directly from the popup with credentials: 'omit', so no cookie ever rides along. Responses cache in chrome.storage.local for fifteen minutes, and every cache write goes through a per-key serialize queue, because two concurrent refreshes doing read-modify-write on the same key is exactly the storage race that has bitten this shelf of extensions before. When a feed is down, the panel serves the stale cache and says it's stale — which beats an empty panel every time.
A fan project's honesty posture
This is an extension about somebody else's story. So the project page carries a "what is ours, and what is not" section stating the line plainly: Kingdom Hearts belongs to Square Enix and Disney; series names appear in the extension as facts about the series; every line of compendium prose is original writing with a KHWiki source link; the art — in the extension and in the store assets — is original, with no game assets and no character likenesses anywhere. The store listing will say the same thing in the same words.
The listing chip on the project page reads exactly what's true today: in preparation, not submitted. When it clears review, the chip becomes a button.
Project page (features + full privacy policy): https://dhseadev.online/projects/kh4-companion/
The rest of the shelf: https://dhseadev.online/projects/
Top comments (0)