About
Learn the mission, tech stack, and high-level architecture of Harmony
Harmony
📖 This document is a living reference and will be updated as the project evolves.
Project Mission
Harmony’s mission is to make personal music analytics accessible, beautiful, and open-source. We help users understand their listening habits, discover insights, and share findings securely—all while providing maintainers a modern, well-typed codebase built for speed and extensibility.
Tech Stack
Layer | Technology | Why We Chose It |
---|---|---|
Application Framework | Next.js 16 (App Router) | File-system routing, React Server Components, edge-ready deployment. |
UI Library | React 19 with Server Actions | Latest React features, seamless data fetching, and progressive enhancement. |
Styling | Tailwind CSS v4 + Shadcn UI | Rapid styling, accessible components, and design consistency. |
State & Async | React Query + Zustand | Predictable data-fetching & caching strategies. |
Database | PostgreSQL via Drizzle ORM | Type-safe SQL, easy migrations, and portability. |
Repo Management | Turborepo | Incremental builds, caching, and monorepo DX. |
Auth | @repo/auth (NextAuth.js v5 under the hood) | Secure OAuth, extensible adapter, first-class TypeScript support. |
CI / CD | GitHub Actions + Vercel / Docker | Fast preview deployments & flexible self-hosting. |
High-Level Architecture
Folder Structure (Excerpt)
apps/
web/ ← User-facing analytics application
docs/ ← This documentation site (Fumadocs)
studio/ ← Developer studio & DB migrations
api/ ← API app (Hono.js)
packages/
ui/ ← Shared UI components (shadcn and customs)
database/ ← Drizzle config & schema
auth/ ← Authentication helpers
spotify/ ← Spotify API SDK
config-eslint/ ← Shared ESLint configuration
config-typescript/ ← Shared TypeScript configuration
web-tests/ ← End-to-end & unit tests
zustand-cookie-storage/ ← Zustand cookie storage helper
Data Flow
- The Web App fetches data from Spotify via the @repo/spotify package.
- Data is persisted in PostgreSQL through Drizzle ORM defined in @repo/database.
- Server Actions in Next.js expose strongly-typed endpoints to React components.
- Client components hydrate minimal UI state and leverage React Query for caching.