Skip to main content

Web Player

Next.js web application for music streaming. Replaces the retired apps/web client โ€” see ADR-0011.

๐Ÿš€ Quick Startโ€‹

cd apps/web-player

# Install dependencies (from repo root)
pnpm install

# Start development server
pnpm dev

Application will be available at http://localhost:3001

๐Ÿ—๏ธ Architectureโ€‹

apps/web-player/src follows Feature-Sliced Design (FSD); see ADR-0002. Imports flow downward only: app โ†’ views โ†’ widgets โ†’ features โ†’ entities โ†’ shared.

apps/web-player/src/
โ”œโ”€โ”€ app/ # Next.js App Router โ€” layout.tsx, page.tsx, providers
โ”œโ”€โ”€ views/ # Full-page compositions for one route
โ”œโ”€โ”€ widgets/ # Self-contained sections: Header, Player, Sidebar
โ”œโ”€โ”€ features/ # User interactions: Album, AuthModal, Playlist, Track
โ”œโ”€โ”€ entities/ # Domain objects: Track, User, Player
โ””โ”€โ”€ shared/ # api/, hooks/, store/, ui/, routes/, constants/, validation/

Route files under app/ are thin adapters that render a view โ€” see ADR-0010.

๐ŸŽฌ Landing (/)โ€‹

app/(home)/ serves the landing with its own fonts (Unbounded, Inter, JetBrains Mono); auth and legal pages keep app/(landing)/ with the shared Header and Footer. views/LandingView renders eleven scenes on the server. Its motion engine (lib/engine/: GSAP scenes, a Three.js stage, physics, intro, cursor) is imported only on the client after mount. Without WebGL it switches to 2D fallbacks, and with reduced motion it is a static, scrollable page. The landing copy is a local catalog (en, uk, pl; other locales read English). Styling is Tailwind: lib/styles/landing.styles.ts lists utilities per marker class in cascade order (context rules as arbitrary variants), and lc() merges an element's entries with cn; ui/landing.css keeps only keyframes, the html scroll and cursor locks and the grain data URI. Behaviour and acceptance: web-player landing spec; motion reference: pencil/web-player-design/landing/motion-prototype.html.

๐ŸŽจ Tech Stackโ€‹

  • Next.js (App Router) + React 19 + TypeScript
  • Tailwind CSS v4 + @bitrate/ui-react โ€” design tokens, CVA, shadcn-style components (see ADR-0006)
  • openapi-fetch + TanStack Query โ€” typed API client generated from the NestJS Swagger contract (see ADR-0004)
  • Zustand โ€” cross-component client state (see ADR-0005)
  • React Hook Form + Zod โ€” forms (see ADR-0007)
  • CMAF + MediaSource Extensions โ€” first-party adaptive playback over byte ranges (see ADR-0020)
  • Native fallback โ€” without MSE the same CMAF file plays through <audio> (see ADR-0065)

๐Ÿ”ง API clientโ€‹

// shared/api/client/fetchClient.ts โ€” openapi-fetch + JWT refresh middleware
export const apiClient = createClient<ApiPaths>({ baseUrl: ... })

// shared/api/client/reactQueryClient.ts โ€” openapi-react-query
export const { useQuery, useMutation, useSuspenseQuery } = createReactQueryClient(apiClient)

Components call useQuery/useMutation from reactQueryClient โ€” never raw fetch or Axios.

๐Ÿงช Testingโ€‹

pnpm --filter @bitrate/web-player test:unit
pnpm --filter @bitrate/web-player test:int
pnpm --filter @bitrate/web-player test:e2e
pnpm --filter @bitrate/web-player test:screenshot

๐Ÿš€ Build & Deployโ€‹

pnpm --filter @bitrate/web-player build
pnpm --filter @bitrate/web-player start

Related: