plyr.fm#
music on atproto
check the plyr.fm artist page for the latest auto-generated development podcast!
tech stack
backend#
- framework: FastAPI
- database: Neon PostgreSQL
- storage: Cloudflare R2
- hosting: Fly.io
- auth: atproto OAuth 2.1 (fork with OAuth implementation)
frontend#
- framework: SvelteKit
- runtime: Bun
- hosting: Cloudflare Pages
- styling: vanilla CSS (lowercase aesthetic)
local development
prerequisites#
quick start#
using just:
# install dependencies (uv handles backend venv automatically)
uv sync # For root-level deps, if any, and initializes uv
just frontend install
# run backend (hot reloads at http://localhost:8001)
just backend run
# run frontend (hot reloads at http://localhost:5173)
just frontend dev
# run transcoder (hot reloads at http://localhost:8082)
just transcoder run
features
listening#
- audio playback with persistent queue across tabs/devices
- like tracks with counts visible to all listeners
- browse artist profiles and discographies
- share tracks and albums with nice link previews
creating#
- well-scoped OAuth authentication via ATProto (bluesky accounts)
- upload tracks with title, artwork, and featured artists
- organize tracks into albums with cover art
- edit metadata and replace artwork anytime
- track play counts and like analytics
- publish ATProto track and like records to your PDS
project structure
plyr.fm/
├── backend/ # FastAPI app & Python tooling
│ ├── src/backend/ # application code
│ │ ├── api/ # public endpoints
│ │ ├── _internal/ # internal services
│ │ ├── models/ # database schemas
│ │ └── storage/ # storage adapters
│ ├── tests/ # pytest suite
│ └── alembic/ # database migrations
├── frontend/ # SvelteKit app
│ ├── src/lib/ # components & state
│ └── src/routes/ # pages
├── transcoder/ # Rust audio service
├── docs/ # documentation
└── justfile # task runner
costs
~$35-40/month:
- fly.io backend (production): ~$5/month (shared-cpu-1x, 256MB RAM)
- fly.io backend (staging): ~$5/month (shared-cpu-1x, 256MB RAM)
- fly.io transcoder: ~$0-5/month (auto-scales to zero when idle)
- neon postgres: $5/month (starter plan)
- audd audio fingerprinting: ~$10/month (enterprise API for copyright detection)
- cloudflare pages: free (frontend hosting)
- cloudflare r2: ~$0.16/month (6 buckets across dev/staging/prod)
links#
- production: https://plyr.fm
- API docs: https://api.plyr.fm/docs
- python SDK / MCP server: plyrfm (PyPI)
- repository: https://github.com/zzstoatzz/plyr.fm