Due to Spotify's updated criteria for Web API Extended Access, which requires the developer to be an organization. Which I am not, this project should be self-hosted and managed for a small group of people. Hosting this as a social-media application would not be possible until Spotify remove the mentioned requirement.
A music-based social platform that lets you share playlists, chat with songs, and discover what your friends are listening to!
- 🎶 Share Music — Share songs and discuss with your friends by attaching songs with your messages or posts
- 👥 Collaborative Playlists — Create and share collaborative playlists with your group in real-time
- 📊 Group Statistics — See what your group listens to the most with detailed statistics and insights
- 💬 Real-time Chat — Chat with your group members with song embeds from Spotify and YouTube
- 🔐 Secure Authentication — Login with Spotify or Google via NextAuth.js with encrypted token storage
- Framework: Next.js 16 (App Router)
- Language: TypeScript
- Styling: Tailwind CSS 4
- Database: PostgreSQL with Prisma ORM
- Authentication: NextAuth.js with Spotify & Google OAuth
- Real-time: Supabase Realtime
- UI Components: Radix UI + Custom components
- Node.js 18+
- pnpm (recommended) or npm
- PostgreSQL database
- Supabase project (for realtime features)
- Spotify Developer credentials
- Google Developer credentials
git clone https://github.com/AungS8430/palplay.git
cd palplaypnpm installCreate a .env file in the root directory:
# Database
DATABASE_URL="postgresql://user:password@localhost:5432/palplay"
DIRECT_URL="postgresql://user:password@localhost:5432/palplay"
# NextAuth
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="your-nextauth-secret"
# Spotify OAuth
SPOTIFY_CLIENT_ID="your-spotify-client-id"
SPOTIFY_CLIENT_SECRET="your-spotify-client-secret"
# Google OAuth
GOOGLE_CLIENT_ID="your-google-client-id"
GOOGLE_CLIENT_SECRET="your-google-client-secret"
# Supabase (for realtime)
NEXT_PUBLIC_SUPABASE_URL="your-supabase-url"
NEXT_PUBLIC_SUPABASE_ANON_KEY="your-supabase-anon-key"
SUPABASE_SERVICE_ROLE_KEY="your-supabase-service-role-key"
# Encryption key for storing provider tokens
ENCRYPTION_KEY="your-32-byte-encryption-key"# Generate Prisma client
pnpm prisma generate
# Run database migrations
pnpm prisma migrate devpnpm devOpen http://localhost:3000 to see PalPlay in action!
palplay/
├── app/ # Next.js App Router
│ ├── api/ # API routes
│ │ ├── auth/ # NextAuth authentication
│ │ └── v1/ # REST API v1 endpoints
│ └── app/ # Protected app pages
│ └── groups/ # Group pages
├── components/ # React components
│ ├── app/ # App-specific components
│ │ ├── chat/ # Chat components
│ │ ├── embeds/ # Spotify/YouTube embeds
│ │ ├── groups/ # Group components
│ │ └── playlist/ # Playlist components
│ ├── home/ # Landing page components
│ ├── icons/ # Icon components
│ └── ui/ # Reusable UI components
├── hooks/ # Custom React hooks
├── lib/ # Utility libraries
│ ├── crypto.ts # Encryption utilities
│ ├── prisma.ts # Prisma client
│ ├── realtime.ts # Supabase realtime
│ └── supabase.ts # Supabase client
├── prisma/ # Prisma schema & migrations
├── public/ # Static assets
└── types/ # TypeScript type definitions
See API_ROUTE_V1.md for detailed API documentation.
| Endpoint | Method | Description |
|---|---|---|
/api/v1/health |
GET | Health check |
/api/v1/groups |
POST | Create a new group |
/api/v1/groups/:groupId |
GET | Get group details |
/api/v1/groups/:groupId/join |
POST | Join a group |
/api/v1/songs |
GET | Search/get song details |
/api/v1/invites |
POST | Create invite link |
# Start development server
pnpm dev
# Build for production
pnpm build
# Start production server
pnpm start
# Run linter
pnpm lint
# Fix lint issues
pnpm lint:fix- Provider tokens (Spotify, Google) are encrypted at rest using AES-256
- Plaintext tokens are cleared from the database after encryption
- All API endpoints require authentication where appropriate
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.
Made with ❤️ by AungS8430