Thomas Reggi's Profile Image

@thomasreggi 🌸

Recreating Mastodons Audio Player as a Web Component

December 4, 2023 (Syndicated From

Cover Image

TLDR: I recreated mastodons audio player as a web component, available reggi/mastodon-audio-player-web-component.

What was the goal?

The goal was to have a audio-player embed like this:

<audio-player src="/file.mp3" poster="/image.jpg"></audio-player>

The goal was also to have it look exactly like the audio-player that mastodon uses.

an image of the audio player


I was creating a Astro component MastodonStatus, something like:

<MastodonStatus href=""/>

And I really wanted to display all the extra post-types, images, poll, video, but when it came to audio there was an issue, there was no drop-in player that resembled the mastodon player. Mastodon wrote the original player using React, so it wasn’t exactly easy to implement as it was. I really just wanted a web-component version to exist for me to drop in and pass the mp3 and an image and be on my way.

Once I started to dive into it and reverse engineer the existing player I started to have hope that it was possible. Everything from the custom volume-slider to figuring out the visualizer was pretty complex. This was also my first time working with the web Audio api, which was surprisingly easy to work with.

Making and working with a complex web-component like this wasn’t simple but there are some things that helped along the way.

  1. No template or style tags, I went pure in-js solutions for all dom elements and styles. I think this saved me in the long run. I hate working with long template strings for html and css.
  2. Grouping initializable elements in a class method, I would break down every element into a function and attach it to it’s parent at the very end, makes it easy to call on elements in other methods.
  3. Grouping all event handlers, this made it easy to track all the events within the component.

What’s next?

I’m hoping that other people will find this useful. In an ideal world mastodon also would adopt this component and the community can build on it and make it better. There’s some work needed to make sure that the component is accessable, but it was a lot of work to get where I am (I feel like I just lifted a bounder up a mountain). I’m totally open to any pull-requests that address any accessability issues with the component. Let’s try and push web-components to be a better standard that are meant to be shared, worked on, and maintained collectivley.

Project Context

This project was born as a dependency to another project astro-cache-embed. The projects look something like this, with each being a dependency of the other: -> astro-cache-embed -> mastodon-audio-player-web-component. Here’s a demo of the mastodon-embed. Here’s a demo of the mastodon-audio-player-web-component.