ENTERING STUDIO...
No track selectedSelect a beat to start

Tech Stack

Built for Performance & Creativity

A modern full stack Next.js portfolio with OAuth 2.0, AWS cloud integration, and custom audio playback architecture.

Languages & Framework

Next.js 16React framework + API routes
React 19
TypeScript
Tailwind CSS
Motion (Framer)

Cloud & Backend

AWS S3Cloud storage for audio files
Spotify API + OAuth 2.0Web Playback SDK + token refresh
VercelServerless deployment & hosting

State & Data Management

React Context APIGlobal playback state & queue management
In-Memory CachingS3 URL caching with 55min expiration
Cookie-Based SessionsSpotify OAuth token storage

Key Features

Spotify OAuth 2.0 Integration

Full OAuth flow with cookie-based session management, automatic token refresh, and server-side token caching. Supports both client credentials and user authorization flows.

AWS S3 Pre-Signed URLs

Dynamic audio delivery with 55-minute URL expiration and intelligent caching. Server-side signing prevents credential exposure while maintaining performance.

Dual Audio Sources

Unified playback interface supporting both HTML5 Audio API for beats and Spotify Web Playback SDK for streaming. Context-aware controls adapt to the active source.

Persistent Audio Playback

Audio continues playing seamlessly across page navigation using React Context and root layout mounting. Smart state management prevents interruptions during route changes.

Backend API Routes

Audio Delivery

/api/beats
Returns all beats with metadata
/api/beats/signedUrl
Generates a signed URL for a specific beat

Spotify OAuth

/api/spotify/login
Initiates Spotify OAuth 2.0 authorization flow
/api/spotify/callback
Handles OAuth callback and exchanges code for tokens
/api/spotify/token
Retrieves or refreshes Spotify access token

Spotify Data

/api/spotify/playlists
Fetches user playlists from Spotify API
/api/spotify/stats/topTracks
Fetches user's most played tracks
/api/spotify/stats/topArtists
Fetches user's top artists

Under the Hood

components/PlayerBar.tsx
useEffect(() => {
  if (audioRef.current && track?.audioUrl) {
    audioRef.current.load()
    audioRef.current.play()
      .then(() => setIsPlaying(true))
      .catch(err => console.error('Play error:', err))
  }
}, [track?.audioUrl])

function handleSeek(e: React.MouseEvent<HTMLDivElement>) {
  if (!audioRef.current) return
  const rect = e.currentTarget.getBoundingClientRect()
  const percent = (e.clientX - rect.left) / rect.width
  audioRef.current.currentTime = percent * duration
}

Performance

< 2s
First Load
~220KB
Bundle Size
95+
Lighthouse

Security & Best Practices

Environment Variable Management

  • All secrets in .env with .gitignore protection
  • Separate client and server environment variables
  • Vercel environment variable configuration

Cookie Security

  • HttpOnly cookies for sensitive tokens
  • Secure flag in production
  • SameSite attribute for CSRF protection

API Route Protection

  • Server-side only secret access
  • Token refresh logic in API routes
  • Error handling without exposing internals

Type Safety

  • Strict TypeScript configuration
  • No any types in production code
  • Discriminated unions for track types

Check Out The Code

View the full source code, architecture decisions, and implementation details.Clean codebase • Full TypeScript • Production-ready

View on GitHub →