- Overview
- Live
- Visualizers
- Per-page tour
- Quick Start
- Architecture
- Stack
- Press kits — auto-generated
- TikTok-ready clips
- AI DJ chat
- Adding a new release
- Scripts
- Contributing
- License
bZ Music is the production codebase behind music.megabyte.space — the live website for hustle-gospel artist bZ (Brian Zalewski, Newark NJ). It's a vanilla TypeScript single-page app on Cloudflare Workers, designed to run an entire indie music career — playback, distribution, press, social — from a single repo with one operator.
What makes it different:
- Real Web Audio visualizers, not React canvases — 16+ visualizer modes (starfield, wormhole, nebula, mirror-wave, plasma, …) driven by the actual FFT of the playing track. Beat detection from
AnalyserNode, key estimation from KS algorithm, per-frame at 60 fps. - Whisper-aligned karaoke — every track ships per-word timestamps in
public/lyrics/<id>.json, produced by OpenAI Whisper-1 + Needleman-Wunsch alignment against the source Suno lyrics. 94%+ average match rate. - Auto-generated per-track press kits at
/press/{trackId}— cinematic cover backdrop, 30s preview button, drop-cap bio, related-tracks list, sync availability, print-ready. Send a journalist one URL. - Vertical TikTok clips at
/clip/{trackId}— 9:16 viewport with synced karaoke + brand watermark, designed to be screen-recorded straight from iPhone Control Center. - AI DJ chat powered by Cloudflare Workers AI (Llama 3.3 70B) — knows the catalog, the current track, the page you're reading. Slash commands, persona switching, voice input, drag-drop attachments.
- No build server, no Docker, no CI complexity —
npm run build && npx wrangler deployships everything (worker + static SPA + audio + lyrics + manifests) in under 90 seconds.
music.megabyte.space — home view |
Bootleg From Tomorrow — album page |
Every track is analyzed in real time and rendered through one of 16+ visualizer modes. Each maps the FFT, beat detector, and per-band amplitude streams differently — same audio, wildly different visuals. Mode is per-session, picker accessible via the topbar HUD chip.
![]() Wave — the classic time-domain scope |
![]() Mirror Wave — symmetrically reflected |
![]() Starfield |
![]() Galaxy |
![]() Supernova |
![]() Constellation |
![]() Aurora |
![]() Nebula |
![]() Wormhole — perspective tunnel |
![]() Vortex — accent-tinted spiral |
![]() Monolith |
![]() Bars |
![]() Sunburst |
![]() Lissajous |
![]() Kaleidoscope |
![]() Plasma |
Long-form pages live in a single non-modal dialog over the player, so audio keeps playing while you navigate. Drop-cap leads, framed figures, accent eyebrow pills, scroll-progress hairline, sticky chip-rail nav with Home button.
Auto-generated for every track in src/data.ts. Cinematic cover backdrop, sticky topnav (Home + Press kit + Play), drop-cap bio, 30s inline preview, More from bZ related-tracks list, lyric quote, print-ready.
Slide-in panel triggered by ⌘K or the floating FAB. Streaming via Workers AI Llama 3.3 70B. Persona switching, slash commands, drag-drop attach, voice input. Knows the catalog + the current track + whichever content page you're reading.
git clone https://github.com/HeyMegabyte/bzmusic.git
cd bzmusic
npm install
npm run dev # local dev server at http://localhost:5173Deploy to Cloudflare:
npx wrangler login # one-time
npm run build # tsc → vite → embed bundle → og card regen → tracks manifest
npx wrangler deploy # ships worker + static SPA + assetsRequired Cloudflare account features:
- Workers (free tier OK)
- Workers AI (Llama 3.3 70B FP8-fast) — free tier OK for low traffic
- KV namespace named
COUNTERS - (Optional) Browser Rendering — used by
/clipfor automated MP4 capture - (Optional) Workers Tracing — set
[observability] enabled = trueinwrangler.toml
┌───────────────────────────────────────────────────────────────────────┐
│ Cloudflare Worker (worker/index.ts) │
│ ├─ / → SPA shell (HTMLRewriter SEO swap) │
│ ├─ /{album} /{album}/{tr} → SPA shell (deep links + canonical) │
│ ├─ /press/{trackId} → server-rendered press kit HTML │
│ ├─ /clip/{trackId} → 9:16 TikTok-ready vertical page │
│ ├─ /api/ai/chat → Workers AI Llama (stream + non-stream) │
│ ├─ /api/spotify/track → Spotify search, KV-cached 24h │
│ ├─ /api/spotify/artist → followers + popularity, KV-cached 1h │
│ ├─ /api/subscribe → Listmonk subscriber add │
│ ├─ /api/push/* → web-push subs + send (VAPID) │
│ └─ /audio/* /lyrics/* → served via env.ASSETS │
│ │
│ Static SPA (src/main.ts, src/visualizer.ts, src/audio.ts, ...) │
│ ├─ AudioEngine → 1 persistent <audio>, FFT @60fps │
│ ├─ Visualizer → 16+ modes driven by FFT + beat phase │
│ ├─ AI Chat → SSE consumer, slash registry, widgets │
│ ├─ Content pages → non-modal dialog over player │
│ └─ Topbar / transport → home + chip-rail (story mode) │
│ │
│ Data layer (src/data.ts, src/suno-meta.ts, src/content-pages.ts) │
│ ├─ ALBUMS 7 records → cover, tagline, trackIds, accent │
│ ├─ TRACKS 59 records → title, file, vibe, lyrics, wisdom │
│ └─ SUNO_META → per-track sunoId, BPM, key, audioUrl │
│ │
│ Tooling (scripts/*.mjs) │
│ ├─ fetch-suno-lyrics → pull lyrics from suno.com /api/feed │
│ ├─ align-whisper-lyrics → OpenAI Whisper + Needleman-Wunsch │
│ ├─ gen-og-cards → DALL-E per-track unfurl cards │
│ ├─ gen-tracks-manifest → public/tracks.json (drives /press) │
│ ├─ gen-sitemap → sitemap.xml + robots.txt │
│ ├─ build-favicon-set → 14-variant favicon set │
│ └─ send-curator-outreach → Resend-powered press-kit emails │
└───────────────────────────────────────────────────────────────────────┘
| Concern | Choice |
|---|---|
| Frontend | Vanilla TypeScript + Vite v6 — no UI framework |
| Runtime | Cloudflare Workers (edge), Wrangler v4 |
| State | KV COUNTERS (plays, shares, rate limits, push subs, listmonk cache) |
| Audio | Web Audio API · AnalyserNode FFT · Krumhansl-Schmuckler key detection |
| AI | Workers AI Llama 3.3 70B FP8-fast (chat) · 3.1 8B fallback |
| Lyrics sync | OpenAI Whisper-1 + Needleman-Wunsch alignment |
| Image gen | OpenAI gpt-image-1 (album covers, OG cards, content figures) |
| Resend + Listmonk | |
| Push | Web Push w/ VAPID |
| Cast | Chromecast default receiver + custom app 228565CB |
| Tests | Playwright v1.59 E2E @ 6 breakpoints vs PROD_URL |
Every track in src/data.ts gets a /press/{trackId} URL with zero per-track configuration. The Worker renders the page server-side using the track title (slug → Title Case), looks up Spotify metadata on demand for the album art + duration + popularity, falls back to the local /art/cover-{trackId}.jpg if no Spotify match.
Send to a curator:
Hi [name],
bZ — Newark hustle-gospel. "Chef Lu Stew" is a 2:59 cinematic gospel-trap cut.
Press kit: https://music.megabyte.space/press/chef-lu-stew
TikTok clip: https://music.megabyte.space/clip/chef-lu-stew
Spotify: https://open.spotify.com/track/7iXeCejHToTccIklUePuem
Sync clearance available. Faith-positive cues welcome.
— Brian (bZ)
The scripts/send-curator-outreach.mjs script bundles this as a templated Resend send for confirmed curator addresses.
/clip/{trackId} renders a 1080×1920 vertical surface — cover art floating with a slow drift animation, lyric karaoke synced to the audio, BPM/key chips, brand watermark. Open on a phone, hit Play 15s, screen-record from Control Center → upload to TikTok/Reels/Shorts.
https://music.megabyte.space/clip/bootleg-from-tomorrow
https://music.megabyte.space/clip/chef-lu-stew
⌘K opens the panel. Powered by Cloudflare Workers AI (Llama 3.3 70B FP8-fast for normal mode, 3.1 8B as automatic fallback on transient failures). The chat is page-aware — it knows what track is playing, what content page you're reading, your recent listens. Drag-drop any file from the page to attach context. /shortcommands lists every slash command.
Examples:
/track birch-swing-heaven— open the track details widget/album canopy— load the album metadata/pin <note>— pin a fact for the chat to remember/voice— toggle voice input (Whisper STT)/snippet save <name>— save a reusable prompt fragment
The Bootleg From Tomorrow album was added in a single session using this flow:
- Drop MP3s into
public/audio/{slug}.mp3(kebab-case filenames) - Run
node scripts/fetch-suno-lyrics.mjsto pull source lyrics from your Suno feed - Append track + album entries to
src/data.ts(use any existing track block as a template) - Generate cover art:
node scripts/gen-covers.mjs <album-id>(or paste your own) - Whisper-align:
node scripts/align-whisper-lyrics.mjs <track-slug>— producespublic/lyrics/{slug}.json - Append per-track SUNO_META entries (BPM/key/duration parsed from Suno style tags)
npm run build && npx wrangler deploy
Press kits, TikTok clips, search results, and the per-album visualizer accent all auto-update from the data layer.
npm run dev # vite dev server
npm run build # tsc -b + vite + embed bundle + prebuild
npm run test:e2e # Playwright PROD smoke
npx wrangler deploy # ship
node scripts/fetch-suno-lyrics.mjs # pull suno feed → data/suno-feed.json
node scripts/align-whisper-lyrics.mjs <slug> # whisper + needleman-wunsch
node scripts/gen-og-cards.mjs # per-track DALL-E OG cards
node scripts/gen-tracks-manifest.mjs # public/tracks.json (powers /press related)
node scripts/build-favicon-set.mjs # full real-favicon-generator output
node scripts/send-curator-outreach.mjs --to=... # Resend email to a curatorThis is bZ's production codebase, so PRs that change branding, copy, or musical content won't land. But pull requests are welcome for:
- New visualizer modes in
src/visualizer.ts - New AI chat widgets in
src/ai-widgets.ts - New press-kit / clip layouts in
worker/index.ts - Tooling improvements in
scripts/ - Accessibility / performance fixes
See CLAUDE.md for the agent-collaboration brief that powers this repo's day-to-day.
Code released under MIT.
Music + lyrics + cover art + the bZ name and likeness are © Brian Zalewski / Megabyte Labs and all rights reserved — fork the engine, don't fork the catalog. See LICENSE-CONTENT.md for details.




















