# PocketChords A rip-off of [Ultimate Guitar](https://www.ultimate-guitar.com/) with a focus on mobile users, without any ads or subscription. Self-hosted, open source and free to use. ## Features - Import chord sheets from Ultimate Guitar URLs or HTML files (bulk import supported) - Transpose chords up/down with one tap - Piano keyboard and guitar fretboard chord diagrams - Capo support with sounding-key display - Adjustable font size (S/M/L) for readability while playing - Search and sort your library - Dark/light theme - PWA — add to home screen for native feel - JWT auth with registration/login - OpenAPI docs at `/docs` ## Architecture Hexagonal / ports-and-adapters with CQRS in the application layer. See `architecture.mmd` for the full diagram. ``` crates/ domain/ # entities, value objects, ports, domain services application/ # use cases: songs/, tabs/, auth/ (commands, queries, deps) presentation/ # axum HTTP server, routes, extractors, OpenAPI api-types/ # request/response DTOs infra-wiring/ # shared config (AppConfig) adapters/ sqlite/ # SQLite persistence (songs, users, refresh sessions) ug-parser/ # Ultimate Guitar HTML parser auth/ # JWT + Argon2 password hashing app/ # React Router SPA (Tailwind, shadcn/ui) ``` ## Quick start ```bash # prerequisites: rust, node # run locally (builds frontend, starts backend on :8000) make dev # or backend only (if frontend already built) make dev-api # run checks (fmt, clippy, tests) make check ``` ## Deployment Single Docker image serves both API and SPA: ```bash # build and push to private registry make deploy # or with a specific tag ./deploy.sh --tag v1.0.0 ``` ### Environment variables | Variable | Default | Description | | ---------------------- | ----------------------------- | ------------------------------ | | `DATABASE_URL` | `sqlite://./pocket-chords.db` | SQLite connection string | | `HOST` | `0.0.0.0` | Bind address | | `PORT` | `8000` | Bind port | | `JWT_SECRET` | _(required)_ | Secret for signing JWTs | | `JWT_TTL_SECONDS` | `900` | Access token TTL (15 min) | | `REFRESH_TTL_SECONDS` | `2592000` | Refresh token TTL (30 days) | | `ALLOW_REGISTRATION` | `false` | Enable user registration | | `CORS_ALLOWED_ORIGINS` | `*` | Comma-separated origins or `*` | | `SPA_DIR` | `./app/build/client` | Path to SPA static files | ## License MIT (see [LICENSE](LICENSE) for details).