Introducing Podrain, a web-based, offline-capable podcast app
Tags: mithriljs, tailwindcss, showdev, offlinefirst
Published: 2020-03-14 01:41:09

---
title: Introducing Podrain, a web-based, offline-capable podcast app
cover_image: https://i.imgur.com/YDQdP3d.png
published: true
description: My attempt to overcome the limitations of pure web apps to deliver an uncompromising podcast-listening experience
tags: mithriljs,tailwindcss,showdev,offlinefirst
---
I've been a fairly avid listener of podcasts since 2005, which is around when Apple introduced them to iTunes. I was pretty embedded in the Apple ecosystem back then, so I didn't really care that there wasn't a good way of listening to podcasts on non-Apple devices. 

Over the years, however, I have been distancing myself from Apple more and more, to the point where I now only use Apple devices when I need to build and deploy iOS projects. I've been developing an allergy to monopolistic lock-in and censorship of which apps can run where. I've embraced the web as much as possible, as both a user and a software developer, because it is the most device-agnostic standard out there today. If your device has a screen, and a web browser, the chances of a web-based app working on it are actually pretty high.

But, as far as podcasts were concerned, I found it really tough to find a non-Apple app that had everything I wanted. Ease of use, offline listening, ability to back up and sync with other devices, and run on any device. I'm an Android user now, so I've been using Podcast Addict, which is a great app. But, it's exclusive to Android. I wanted to give Pocket Casts a go, but the reliability was so-so according to reviews, and I need something I can trust. I tried Stitcher, but it was just too hard to listen to podcasts without being distracted by all the advertising and non-podcast-related stuff. I use Spotify for music, but their interface just isn't well-suited for podcasts, and besides, I want to support podcasts as an open web standard that no big entity seeks to control, which even Apple respects (in regards to podcasts).

So, I decided to scratch my own itch and take a crack at this problem myself.

## Introducing Podrain

[Podrain](https://github.com/podrain/podrain) is a web-based podcasting app with some very basic features:

- Offline listening
- Episode queue that spans across podcasts
- Pure focus on audio podcasts (no radio, video podcasts, news, etc.)
- Sync backup to a cloud server

## App structure

The app was built with my "trusty tools", [Parcel](https://parceljs.org/), [Mithril](https://mithril.js.org/) and [Tailwind](https://tailwindcss.com/). I've been using this stack lately for almost every new project.

## Challenges

It took me about three weeks of part-time effort to build this app, which I open-sourced yesterday. It's still pretty rough around the edges and needs more documentation, but it works well enough and I've replaced my current podcast app with it! Besides regular web development woes, here are some of the challenges I faced and how I overcame them.

### The offline problem

I've actually tried to build this app before, but as a web app that *completely relied* on having a really good internet connection the entire time. This obviously doesn't work for someone who spends much of his time in one of the most rural areas of the United States. So, I had to take a different approach and ensure that this app could work in a way that didn't need *any* Internet connection after the initial app was loaded. After all, I listen to podcasts quite often while driving in areas with not so much as a 3G cell signal. To solve that, I used [PouchDB](https://pouchdb.com/) which made it really easy to store all the needed podcast metadata in browser storage, and have it persist even when the app web page is closed.

In addition, I needed the actual audio files to be saved to the device, rather than streamed. This is very important for both maintaining an uninterrupted listening experience as well as to avoid risking extra charges for excessive cell data usage. I used [localForage](https://localforage.github.io/localForage/) to give the user the option to store the audio files in their browser's IndexedDB storage system as binary `Blob`s.

Unfortunately, the audio file download feature won't work well on iOS because they only allow 50-megabyte files for domain, when a single MP3 file for a podcast episode could easily be twice that. Will probably have to disable the feature for iOS browsers unless Apple has a change of heart.

### CORS for podcast feeds and media

This was actually a very tough problem to solve that seemed to have only bad options. The easiest way was to disable CORS in my browser (using a browser plugin), but that's very unsafe as I would be quite vulnerable to XSS and other nasty attacks if I visit other websites. The other option is to use a proxy, but downloading hundreds of megs data using a public proxy would easily overwhelm many of these proxy sites and I might even have my IP address banned. 

However, there is a Node server called [CORS Anywhere](https://github.com/Rob--W/cors-anywhere/) that can take all requests to a domain, and forward them with different CORS headers that allow the browser to accept content from different domains via XHR. It turns out there is an excellent [pre-configured Heroku dyno](https://elements.heroku.com/buttons/puzzleboss/cors-anywhere) anyone can spin up and run their own proxy, likely for free! So that's what I did. Then, in the app, I put the URL to this proxy and I'm off to the races. I may find a better way of setting that up more automatically down the road, but once it was set up, I'm able to start adding podcasts and listening to episodes!

## Future

The app has some real rough edges, but they will be worked out over time. Eventually, I want to add service workers and a web app manifest file to make it a true PWA. Also, the interface needs to be optimized for tablet/desktop, since it was built mobile-first for the smallest screen (where I use it the most).

Hopefully, this app can help serve as one of many examples of just how far you can take pure web technologies if you give them a chance.