Introducing synthwave.live, a nostalgic musical odyssey

I stumbled upon the synthwave genre[1] when a friend of mine sent me a link to The Midnight’s America Online track on YouTube. I became a little obsessed with the synth-y nostalgia of it all and ended up diving into several artists’ discographies and bookmarking compilations I would find on YouTube.

In particular I enjoyed working to the sound of (mostly) instrumental synthwave mixes. I was making my own playlist of mixes at first but what I really wanted was “YouTube but it’s just synthwave mixes.” I started looking into it and it turns out YouTube’s Data API could support what I wanted.

The idea was to grab all the videos I had been finding and add them to a website that was more appropriate for music playback. That meant more advanced playback controls and behavior—ability to navigate track lists, now-playing notifications, and other features. I’m not gonna lie it was also fun to put a synthwave-y aesthetic on the whole thing—add some sweet fonts, throw in some pinks and purples.

I started searching for domain names—the obligatory first step of any new project—and settled on synthwave.live (I also nabbed chillwave.live and retrowave.live while I was there). Never mind I wasn’t planning on posting live music. Just notice how pristine the domains are!

I designed a quick logo and paid an illustrator on Fiverr to make a favicon. It was off to the races.

Oh yeah, that was in May 2020. Turns out I built it and quietly ran it for over a year before deciding to write about it. What can I say, I’m lazy and also I wanted to make sure I could keep it updated. Well, I did. So now I’m officially introducing synthwave.live.

Screenshot of homepage showing a listing of video thumbnails in a grid.
The homepage

Concerns

I had a few reservations about the project but nothing that ultimately deterred me from building it.

Overview of features

Listing view

The homepage is a listing of all videos on the site sorted by date. You can also sort the list by views on YouTube. This keeps the homepage fresh.

Single video view/player

This is the bread and butter of the site and one of the main reasons for the project existing. It’s laid out similar to a single video page on YouTube with some key differences.

Screenshot of single view. Shows an embedded YouTube video with some metadata below.
Single view

User accounts and favorites

I wanted to bookmark my favorite mixes for easy reference later so I added user accounts. Once signed in, an Add to Favorites button appears on the player page. Clicking Favorites in the menu bar will take you to a listing view of all your favorite videos.

The only purpose of user accounts at the moment is for keeping track of Favorites. I don’t have any other immediate plans for accounts.

A basic search view exists that lets you perform searches against the full titles and descriptions of videos or titles only. The search is pretty basic but serviceable. It’s all frontend-powered so it first has to download an index file which is a bit large.[2]

Developer notes

Here I’ll cover some of the technical details of how the site works. The birds-eye view is this:

YouTube Data API

As I mentioned previously, synthwave.live is made possible because of YouTube’s Data API. I’m keeping a manually curated list of channel IDs and playlist IDs. If the whole channel is nothing but synthwave mixes I grab all the videos from the channel. Otherwise I grab playlists that fit the theme of the site. I prefer using the whole channel if possible because people sometimes forget to update their playlists.

Using those IDs I run a NodeJS script that makes a series of requests to the API and the result is a big JSON file of video information. I do a bit of filtering after the fact. For example, I don’t want single-track videos on the site so I enforce a minimum duration of ten minutes.

Static site generation with Eleventy

This was my first project on which I used Eleventy and it’s definitely a tool I’d use again. Its most appealing feature in this case is its ability to use various data sources as input. My particular setup is a little complicated but, in short, I take the big JSON data dump and use it to generate all the different pages needed—paginated listing views, single views, and one-off pages like the one that lists every YouTube channel used on the site. I’m even using Eleventy to generate a small JSON file for each video (I call it a fragment) that I can request when I need information about a particular video.

All the pages get built by Eleventy and those, along with styles and scripts, get deployed to the server.

Vue for interactivity and Userbase for persistent user data

For frontend interaction I’m using Vue 2. I take advantage of Vue’s reactivity system to sync up various parts of the UI, primarily the moving parts on the single view like the mini player, but also on the search page and user authentication pages.

Since the app is all frontend I’m using a service called Userbase to handle authenticating users and storing and retrieving their favorites. It’s a neat service that was fairly straightforward to integrate and kept me from needing to implement a backend. It costs $89/year for the standard plan which is a great value for what you get.

I’m sure I could do a better job with the asynchronous nature of the whole thing but it works well enough for how I’m using it.

Track list parsing

Before making the site, I was listening to mixes directly on YouTube using an extension called YouTube Tracklist Control. I thought it was really cool how it parsed tracks using the description text (if the publisher provided timestamps). As the code for that extension is public domain, I was able to use the parsing code with a little modification to support all the track-based features on the site. There are times when either track lists aren’t provided or they’re provided in such a way that the parser doesn’t recognize. In those cases, the video still plays but playback information and controls are limited.

Screenshot of single view scrolled down past the video. Showing video title, published date, links back to YouTube, full text description, sidebar with interactive tracklist.
Single view details

Popout Player

I had never tried interacting with a new browser window before so it was a learning experience. I ended up using an event system to communicate state between the windows as needed. I wish it was possible to set a window to be a floating window (always on top of other windows) but I can see where that would be terrible for security.

Screenshot of the popout player. It’s a small window showing playback controls, the track title, the video title, the channel name, and a playback progress bar.
Popout player

Infrastructure

That’s a silly term to use in this case but here’s my setup.

I’m aware GitHub can deploy this for me now but I already have it set up this way. If you’re thinking it would be better to deploy to Netlify or some other fancy service I say to you… yeah you’re probably right. I’m a curmudgeon stuck in my ways. Get off my lawn.

Roadmap and closing thoughts

I’m mostly letting it hum along as-is, just running the update script every week to grab new videos and occasionally adding new content sources. That said, there are some features on my radar.

It was a fun project to build. I think it took me about three or four weekends for the initial build and then a little work here and there to fix things. The weekly maintenance is very easy. I run one script that gets the data from YouTube and builds a preview of the site for me to inspect. If I like what I see I can run another script to automatically commit and push it, which triggers the deployment.

I use the site as my own personal audio player almost every day, especially during working hours. If you like synthwave or just like to listen to instrumental background music, give it a try and let me know what you think.

Go to synthwave.live →

[^track parsing]: I realize technically YouTube can do most (all?) of this but it isn’t as straightforward. On synthwave.live I’m leaning heavily on track list parsing so that it feels like you’re viewing a real list of individual tracks, not a video with timestamp links.


  1. When I say synthwave, I usually also mean chillwave, retrowave, outrun, darksynth, and other sub-genres. ↩︎

  2. The index file is about 460kb gzipped at the time of this article and growing every week. “Index” is probably a misnomer since this file includes full descriptions of videos. But it is a stripped down version compared to the all the data I get back from YouTube. ↩︎