FiveGuesses
Ein tägliches Song-Ratespiel für den Browser: fünf Versuche, und jeder Fehlversuch verdoppelt die Hörprobe, die Sie hören (1, 2, 4, 8 und 16 Sekunden).
- Lizenz
- MIT
- Status
- öffentlich
- Kategorie
- Spiele
- Repository
- github.com/luminare-dev/FiveGuesses
- Release
- v0.1.0
- Dokumentation
-
- Installation
- Configuration
- Upgrading
- Troubleshooting
- Runbook
- Accessibility
- 0001. Record architecture decisions
- 0002. Pin every action and downloaded tool
- 0003. Secret scanning with the gitleaks binary
- 0004. Draft releases with checksums and build provenance
- 0005. One Expo code base, built for the web first
- 0006. No backend: everything stays in the browser
- 0007. The daily song comes from the day number
- 0008. Previews are streamed, never stored
- 0009. The shell works offline, the audio does not
- 0011. The web build ships in every release
- 0012. Logic tests in Jest, UI tests in Playwright
Nicht verbunden mit oder unterstützt von Apple. Apple Music und die iTunes Search API werden nur genannt, um zu beschreiben, woher die Hörproben der Songs stammen.
Die README und die Dokumentation stammen aus dem Repository und sind auf Englisch.
Why
Daily guessing games work because everyone gets the same puzzle and compares results, but most of them need an account, a backend and a tracker. FiveGuesses keeps everything in the browser: the daily song comes from a fixed list and the day number, stats and streaks stay in local storage, and the 30-second previews are streamed from Apple Music and never stored. The repository shows one Expo (React Native) and TypeScript code base built for the web with react-native-web, playable by keyboard and screen reader, in a light and a dark theme, with an installable shell that opens offline, unit and end-to-end tests and pinned CI.
Quickstart
git clone https://github.com/luminare-dev/FiveGuesses.git
cd FiveGuesses
npm ci
npm run web
The game opens at http://localhost:8081. Node.js 22 is required (.nvmrc).
How it works
Diagram: see the README on GitHub.
Song previews
Previews are 30-second clips streamed from Apple Music through the public iTunes Search API. The app never downloads or re-hosts them, shows a Listen on Apple Music link on every reveal and the line Previews courtesy of Apple Music wherever a preview plays.
Previews courtesy of Apple Music.
Design decisions
The decisions behind this project are recorded as short ADRs in docs/adr/:
- ADR 0001: Record architecture decisions
- ADR 0002: Pin every action and downloaded tool
- ADR 0003: Secret scanning with the gitleaks binary
- ADR 0004: Draft releases with checksums and provenance
- ADR 0005: One Expo code base, built for the web first
- ADR 0006: No backend: everything stays in the browser
- ADR 0007: The daily song comes from the day number
- ADR 0008: Previews are streamed, never stored
- ADR 0009: The shell works offline, the audio does not
- ADR 0010: English strings prepared for translation
- ADR 0011: The web build ships in every release
- ADR 0012: Logic tests in Jest, UI tests in Playwright
Supported versions
| Component | Tested with | Supported |
|---|---|---|
| Node.js | 22.22.0 | 22.x |
| npm | 10.9.4 | 10.x |
| Expo SDK | 57.0.30 | 57.x |
| React Native / react-native-web | 0.86.3 / 0.21.2 | the versions Expo SDK 57 installs |
| expo-audio | 57.0.5 | the version Expo SDK 57 installs |
| TypeScript | 6.0.3 | 6.x |
| Browsers | Chromium 141 (end-to-end tests); Firefox, Safari and iOS Safari not tested | the two latest major versions of Chrome, Firefox, Safari and iOS Safari |
| Web server for the static build | not tested: public/.htaccess is written for Apache 2.4 with mod_rewrite, mod_headers and mod_deflate, and step 6 of the runbook checks its headers on the host |
Apache 2.4.x; any static host without the .htaccess headers |
Fixes go into the latest minor release only. See the security policy for reporting.
Limitations
- Previews need a network connection: the app shell, the song list and your stats work offline, the audio does not.
- The song list is a fixed, curated set of 95 tracks in
assets/songs.json; it is regenerated withnode scripts/seed-songs.mjs, which calls the public iTunes Search API. - English only. The strings are prepared for translation (
src/i18n/), but no other language ships. - Web only. The Expo project can be built for iOS and Android, but only the web build is tested and released.
- No accounts and no sync: stats live in the browser’s local storage and are gone when it is cleared.
- The daily song changes at your local midnight, so players in different time zones get the new song at different moments.
- Mobile browsers require a tap before the first preview plays (autoplay rules); the play button is always the first action.
Results
| What | Value | How it was measured |
|---|---|---|
| Unit tests | 359 tests in 10 files pass | npm test (Jest), 2026-10-24 |
| End-to-end tests | 37 scenarios in 12 files pass in Chromium 141 | npm run e2e (Playwright in Chromium 141, previews stubbed), 2026-10-24 |
| Web build | 194 kB of JavaScript after gzip (684 kB uncompressed) | npm run build prints the bundle size and its gzip size, 2026-10-24 |
| Offline start | the shell, the saved round and the privacy page open with the network switched off | Playwright scenario e2e/pwa.spec.ts (context.setOffline(true), then reload), 2026-10-24 |
| Template checks | 0 findings | python3 scripts/forbidden_words.py, 2026-10-24 |
Development
Node.js 22 (.nvmrc), npm 10 and Python 3.10 or later. The one command that runs the type check,
the unit tests and the web build, as CI does:
npm ci && npm run check
End-to-end tests run against the built app in Chromium: outside CI, npm run e2e uses the binary
at PW_CHROMIUM_PATH (default /opt/pw-browsers/chromium) when that file exists, otherwise the
Chromium that npx playwright install chromium provides, the build that belongs to the
@playwright/test version pinned in the lockfile. CI ignores PW_CHROMIUM_PATH and runs the same
install command with --with-deps. The template checks CI also runs: python3 -m unittest discover -s tests -v,
python3 scripts/forbidden_words.py, python3 scripts/set_byline.py verify and
python3 scripts/check_workflows.py; the linters are listed in docs/install.md.
Keyboard and screen reader: a whole round can be played without a pointer. Tab moves through Statistics, About, the play button, the guess box, Skip, Guess and the footer links; Space on the play button starts the snippet. In the guess box, typing opens the list of matching songs, ArrowDown and ArrowUp move the highlight, Home and End jump to the first and last entry, Enter guesses the highlighted song (or an exact match you typed) and Escape closes the list. Every round event is spoken once through one polite live region, the Statistics and About sheets trap focus and return it to the button that opened them, and no state is shown by colour alone. The full map is in docs/accessibility.md.
Documentation and links
- Installation · Configuration · Upgrade · Troubleshooting · Runbook · Accessibility · ADRs
- Changelog and releases
(each release has
SHA256SUMS; only releases published while the repository is public also carry a build provenance attestation) - Contributing · Code of conduct · Security · Support
- Project page: https://luminare.tech/open-source/fiveguesses/
Not affiliated
Not affiliated with or endorsed by Apple. Apple Music and the iTunes Search API are named only to describe where the song previews come from.
Licence
MIT. The licence covers the code only: the project name, logo, header images
and docs/brand/ are not licensed (see NOTICE).
a Luminare Development open-source project
Lizenziert unter MIT. Quelle: luminare-dev/FiveGuesses, Stand v0.1.0.