Interactive web application · 2026
PokéTunes
Suggests personalized Spotify playlists based on any Pokémon's type, stats, and lore.

PokéTunes — Case Study
Project Overview
PokéTunes is a web application that generates personalized Spotify playlists based on any Pokémon’s attributes. Search for a Pokémon, and the app translates its type, stats, and lore into a curated playlist of real Spotify tracks. A companion “Spirit Pokémon” feature analyzes a user’s Spotify listening history to match them with the Pokémon that best represents their musical identity.
Motivation
Pokémon and music are two universally loved cultural touchstones—but nobody had connected them in a meaningful way. The core question: what if a Pokémon’s type, stats, and lore could translate into a musical identity? Fire types should sound like distorted guitars and heavy drums. Water types should feel like smooth R&B and lo-fi chill. PokeTunes makes that translation real.
Features
Pokémon Search with Autocomplete
- Searches across all 1,025 Pokémon from the National Pokédex
- PokeAPI responses are cached locally for 24 hours to minimize network requests
- Parallel fetches to both the
pokemonandpokemon-speciesendpoints for complete data (stats, types, legendary/mythical status, flavor text)
Playlist Generation
- Pokémon attributes are sent to a serverless edge function that authenticates with Spotify via client credentials
- The function builds keyword-based search queries derived from a type-to-genre mapping system and fetches matching tracks
- Results are aggregated, deduplicated, and returned as a playlist
Type-to-Genre Mapping
Each of the 18 Pokémon types maps to a set of musical genres and keywords:
| Type | Genres / Keywords |
|---|---|
| Fire | Rock, Metal, Hard Rock |
| Water | Chill, R&B, Lo-fi |
| Grass | Folk, Acoustic, Indie Folk |
| Electric | EDM, Synthwave, Electro |
| Psychic | Dream Pop, Ambient, Shoegaze |
| Ghost | Darkwave, Gothic, Post-Punk |
| Dragon | Epic, Orchestral, Power Metal |
| Fairy | K-Pop, Bubblegum Pop, Hyperpop |
| Dark | Trap, Horrorcore, Industrial |
| … | (and so on for all 18 types) |
Stats like speed and attack further influence the energy and tempo of selected tracks. Legendary and mythical Pokémon skew toward epic, cinematic results.
Spirit Pokémon (OAuth-dependent)
- User authenticates with Spotify via OAuth
- The app fetches the user’s top 50 tracks and their associated artist genres
- Genres are converted into a 5-dimension audio profile: energy, valence, tempo, acousticness, instrumentalness
- The profile is compared against a pre-computed database of Pokémon audio profiles using weighted Euclidean distance
- The closest match is returned as the user’s Spirit Pokémon, along with a match score and top personality traits
Shareable Result Cards
- Generated entirely client-side using the Canvas API
- Two aspect ratios: landscape (1200×630) for Twitter/Facebook Open Graph, and portrait (1080×1920) for Instagram Stories
- Cards include the Pokémon sprite, playlist name, type badges, and a stylized background
- Integrated with the Web Share API for native sharing on supported devices, with clipboard fallback
Tech Stack
| Layer | Technology |
|---|---|
| Frontend | React 18, TypeScript, Vite |
| Styling | Tailwind CSS, shadcn/ui component library |
| Backend | Deno edge functions (serverless) |
| APIs | Spotify Web API, PokéAPI |
| Database | Cloud-hosted PostgreSQL |
| Deployment | Lovable Cloud |
Architecture
┌──────────────┐ ┌──────────────────┐ ┌─────────────┐
│ React App │──────▶│ Edge Functions │──────▶│ Spotify API │
│ (Vite/TS) │ │ (Deno runtime) │ └─────────────┘
└──────┬───────┘ └──────────────────┘
│
▼
┌──────────────┐
│ PokéAPI │
│ (REST, cached locally)
└──────────────┘
- Frontend fetches Pokémon data directly from PokéAPI (with 24-hour local cache)
- Edge function receives Pokémon attributes, authenticates with Spotify using client credentials, constructs genre-based search queries, and returns a deduplicated playlist
- Spirit Pokémon edge function handles the OAuth flow, fetches user listening data, computes the audio profile, and matches against pre-computed Pokémon profiles
- Share cards are rendered entirely on the client using Canvas—no server-side image generation needed
Design
PokeTunes uses a dark neon / cyberpunk aesthetic:
- Typography: Orbitron (display/headings) paired with Exo 2 (body text) — both chosen for their techy, futuristic feel
- Color palette: Deep dark background with vibrant neon accents that shift based on the selected Pokémon’s type
- Effects: Neon glow shadows, gradient overlays, and type-colored badges
- Layout: Single-page app with a centered search flow that expands into the playlist result view
Challenges & Lessons Learned
Spotify Developer Platform Restrictions
Spotify’s API access model for individual developers is restrictive. Apps in “development mode” can only be used by manually allowlisted Spotify accounts (max 25). Getting into “extended quota mode” requires a formal review. This meant that OAuth-dependent features (Spirit Pokémon, Save to Spotify) had to be disabled for public users—only the client-credentials-based playlist generation works without user authentication.
Lesson: When building on third-party APIs, always prototype the auth flow early and understand the platform’s access tiers before investing in features that depend on user-level permissions.
Designing Meaningful Genre Mappings
Translating 18 Pokémon types into musical genres required balancing cultural associations (fire = intense) with actual Spotify search results (not every genre keyword returns good tracks). The mapping went through several iterations, testing which keywords consistently returned diverse, high-quality results.
Lesson: API-driven features need to be designed around the API’s actual behavior, not just theoretical mappings. Iterative testing against real data is essential.
Canvas-Based Share Cards
Generating shareable images entirely in the browser (no server-side rendering) meant working with the Canvas API’s quirks—cross-origin image loading, font rendering differences across browsers, and pixel-perfect layout without CSS. Supporting two aspect ratios (landscape for social cards, portrait for Stories) added complexity.
Lesson: Client-side image generation is powerful for eliminating server costs, but requires careful handling of async resource loading and cross-browser rendering differences.
Screenshots
Replace the placeholders below with actual screenshots or screen recordings.
Home / Search
Screenshot placeholder: search view.
Playlist Result
Screenshot placeholder: playlist result.
Share Card (Landscape)
Screenshot placeholder: share card (landscape).
Share Card (Portrait)
Screenshot placeholder: share card (portrait).
Spirit Pokémon Result
Screenshot placeholder: spirit Pokémon result.
Current Status
Live at poketunes.com. Playlist generation is fully functional—search any Pokémon and get a real Spotify playlist. Spirit Pokémon and Save to Spotify features are disabled for public users due to Spotify API access restrictions for non-approved developers.
Gallery
Gallery coming soon
More visuals from this project are on the way.