October 2023 – December 2023
My Role
  • Strategy
  • Branding
  • Product Design
  • Engineering
  • Melt UI
  • Svelte
  • SvelteKit
  • Supabase
  • Spotify Web API
  • TypeScript


In 2021, I read the novel Paul Takes the Form of a Mortal Girl by Andrea Lawlor. Early in the book, Paul gushes about his love of gender-swapped covers:

Some covers deliver the age-old simple pleasures of drag—knowledge, the opportunity to investigate the simulacra and make comparisons, that obscure little frisson of dissonance. Take Joan Baez singing “Virgil Kane is my name… like my father before me, I’m a working man” (which, of course, is originally from The Band’s “The Night They Drove Old Dixie Down)” or Cait O’Riordan from the Pogues crooning, “My name is Jock Stewart, I’m a canny gun man” (from the traditional “I’m a Man You Don’t Meet Every Day”). Joan Baez’s contralto can, if you squint your ears, pass as a farm-boy tenor; Cait O’Riordan’s chalky delivery might be that of a rich ponce.

I listened to each cover and original, enamored with how lyrics could completely transform under another artist’s tone, tempo, and gender.

I began compiling Paul’s songs into a playlist, and then I added more of my own. And more. And more. For another two years.

The Challenge

As my covers playlist grew, so did the tedium of managing it in Spotify. I kept all covers alphabetized (by hand), and I maintained two separate playlists—one for both covers and originals, and another for covers only.

Difficulties organizing in Spotify. The interface makes it challenging to organize songs within large playlists. (Sorting by title exists, but it’s unreliable here—John Denver’s “Take Me Home, Country Roads” deserves to live beside Judy Collins’s “Leaving on a Jet Plane/Take Me Home Country Roads”.)

After managing this playlist for two years, I decided to build a custom solution to host and catalogue covers. I named it Genderswap.fm.

Laying Foundations

This personal project was my first time working directly on the backend. Thankfully, Supabase—an open source alternative to Google’s Firebase—made it easy to get started.

I experimented with alternative data structures and landed on a two table model: one table for songs, and one table for covers, which links two song rows together along with extra metadata about their relation.

A visualization of the database schema for

Database schema. This is the shape of the data for Genderswap.fm.

I decided to use Svelte and SvelteKit for my application framework. I had previously used Svelte in my build for the NYC Boundaries Map, and the addition of SvelteKit made it easy to manage routing, server-side rendering, and API requests. I set up a Spotify Developer account and used the Spotify Web API TypeScript SDK to make it easy for users to search for and enter songs. I also added Melt UI, a Svelte-based component library, to help build the submission form.


For the design, I knew I wanted to allow users to browse by pairs of songs shown together. It wouldn’t be too different from browsing “by album” in any other music tool, but rather than displaying a single album for each result, I’d display original/cover pairs.

From there, users could tap in to view the details of a cover, and listen to the original and the cover side-by-side, with notes about their differences.

Detail page and form field sketches.

Search and filtering sketches.

Exploratory sketches. Ideating around the display of albums, how to structure the submission form, and how to surface filters. I still hadn’t figured out what I would ask users to tag manually, and what I could tag automatically using Spotify’s API.

Finding a Design Language

To communicate the way these covers remix sound, reinterpret lyrics, and reconfigure meaning, I established a visual motif to thread its way through the app: two objects, overlapping and askew. Sharing space, but different.

A grid of albums and covers displayed on

Overlapping visual motif. Intentional overlapping groups the original and cover as a single unit. The cover album is larger and foregrounded for emphasis.

Typography is set in Labil Grotesk, a queer font which topples over itself, unable to rest upright, mirroring the off-kilter elements elsewhere in the app.

Header typography for a detail page within the app. The text reads: Sonata
No. 8 in C Minor, Op. 13 “Pathétique”: II. Adagio cantabile. Jun Fukamachi
covering Ludwig van Beethoven

Labil Grotesk in use. I love the way the ‘O’ falls over, ready to roll off the screen.

While the topsy-turvy contextual alternates were enabled for page-level headings, I disabled them for smaller text to prioritize legibility.

Little Big Features

As with all my work, I looked for opportunities to introduce small but meaningful details.

Automated tagging. Covers are automatically tagged with attributes like “sadder” or “more danceable”, and you can search and filter by tag.

A collection of three browser URL boxes with associated titles. The URLs
are nicely formatted with hyphens and human readable text. The titles are
formatted like "Cat Power's cover of Sea Of Love by Phil Phillips & The

Readable URLs and page titles. Share human-readable URLs which accommodate diacritics and non-Latin characters.

"Girls Just Wanna Have Fun" covered as "Girls Just Wanna Have

“Covered as…” Conditionally see when a cover’s title diverges from the original.

The user has selected ABBA's Dancing Queen from ABBA Gold. A banner says
there's an earlier release, and prompts the user to choose the album
Arrival, which was released 32 years

Earlier release prompting. Behind the scenes, the app will search for earlier album releases for your original song. If one is found, it’ll prompt you to update your submission.

A text message with a preview of the album art and page

Rich social previews. Custom Open Graph images generated using Satori and Sharp display a cover’s title, album art, and tags.

A list of titles displaying remaster dates and other non-title info
scratched out by a red marker.

Just the titles. Remaster dates, “(Featured on…)”, “[From the Movie…]”, and other cruft is stripped out, leaving only the artistic title.

Celebrate contribution. Confetti erupts after each new submission. 🎉

"An input with the label "Your first name (optional)". The input is
prefilled with the name "Eva".

Pre-filled name for repeat submissions. Entered names will be pre-filled for future submissions on the same device.

Paste links into search. Title too hard to type? Just copy and paste the Spotify link.

Explore covers, get a random cover, or submit your own.


I didn’t have any massive ambitions for this app—it was mostly a way for me to learn new technology, and see if I could manage my covers library in a way that felt a little more natural. In that sense, it was a success!

After finishing the first version of the app, I emailed it to Andrea Lawlor, sharing how Paul Takes the Form had inspired me. A few days later, I received this reply:

"Andrea Lawlor email to me, 2:45PM: Whoa this is THE COOLEST thing I have

Andrea Lawlor’s reply. You heard it here, folks. The coolest thing ever.

I was overjoyed. Thanks, Andrea. Thanks, Paul.

Genderswap.fm is now showcased on Made with Svelte and the Utopia.fyi Showcase.


There are many improvements I’d still love to make to the app. At the top of the list is an in-app audio player. I’d also like better search, and a way to automatically generate and sync the Genderswap.fm database to a Spotify playlist. I track all issues and ideas on GitHub, and contributions are welcome.

I learned a lot building this out. The backend is not as scary as it seems, and I taught myself that it’s possible for me to build a full-stack app from start to finish! There’s still more to learn, and I hope to continue working on this project when I have time.