All work

Interactive web application · 2026

PokéTunes

Suggests personalized Spotify playlists based on any Pokémon's type, stats, and lore.

PokéTunes

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 pokemon and pokemon-species endpoints 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)

  1. User authenticates with Spotify via OAuth
  2. The app fetches the user’s top 50 tracks and their associated artist genres
  3. Genres are converted into a 5-dimension audio profile: energy, valence, tempo, acousticness, instrumentalness
  4. The profile is compared against a pre-computed database of Pokémon audio profiles using weighted Euclidean distance
  5. 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)
└──────────────┘
  1. Frontend fetches Pokémon data directly from PokéAPI (with 24-hour local cache)
  2. Edge function receives Pokémon attributes, authenticates with Spotify using client credentials, constructs genre-based search queries, and returns a deduplicated playlist
  3. 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
  4. 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.

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.