BitMidi homepage screenshot

I built a new web app – BitMidi – for listening to free MIDI songs. It’s a historical archive of MIDI files from the early web era. You should check it out at bitmidi.com.

Why build a MIDI website?

I was reminiscing about the days of Geocities and Angelfire, when the web was quirky and fun. In those days, sites often used the <bgsound> HTML tag to include an auto-playing song in the background of a page. Usually the song was in the MIDI file format.

MIDI files were the obvious choice for a few reasons.

First, MIDI files were one of the only audio formats supported by web browsers at the time, along with the WAVE and AU formats.

Second, they were relatively small compared to the contemporary alternatives like WAVE, AU, or even MP3. A typical MIDI file is usually less than 40 kilobytes, compared to multiple megabytes for WAVE, AU, or MP3 files. The secret of MIDI files' incredibly small sizes is explained below!

It’s hard to describe MIDI files if you’ve never heard them before. The MIDI aesthetic is synth-laced, nostalgia-inducing, old-school, and endearing. It’s mixed up with the first DOS video games I ever played and the first websites that I visited as a small child in ‘95 and '96. A textual description can’t adequately capture the feeling of listening to a MIDI.

I was surprised and sad to learn that all major web browsers have removed MIDI file support. Perhaps this happened at the same time that the <bgsound> HTML tag was removed? This explains why I haven’t heard a MIDI in many years!

My quest to play a MIDI file

So, I really wanted to play a MIDI file. When I searching the web for a MIDI websites, I discovered that existing websites were quite disappointing. It was difficult to find a site with a decent user experience. Almost all the top sites were unmaintained or broken in various ways. Most sites could not play back the files directly in the site, requiring them to be downloaded and played in an external program instead.

Quicktime also dropped support for MIDI when Quicktime X was released in 2009 which inconvenienced many musicians and probably stopped many users from playing back (or discovering!) this wonderful file format.

Technically, Apple still offers Quicktime 7 for download, which can play MIDI. But it’s a 32-bit app so it will likely stop working once the macOS version after 10.14 Mojave is released. Also, embarrassingly, the Quicktime 7 download link uses insecure HTTP!

Even the venerable VLC failed to play back the MIDI files I threw at it. (I later learned that VLC can actually play MIDIs and I just got unlucky with the few I tried, hah!)

There were some websites that could convert MIDI to low-quality MP3, and some sites offered inline MIDI playback using Adobe Flash, but they were flaky and impossible to get working in Chrome.

Other websites implemented MIDI players in JavaScript, but they were usually missing instruments or extremely ineffecient multi-megabyte cross-compiled Emscripten libraries.

There was only one MIDI player website that really impressed me and that is Muki. Muki had the best-sounding web MIDI player but sadly their MIDI library, while impressive, is hard to browse since there’s no index listing, just radio mode and limited search. I wanted to lookup specific MIDIs that I remembered, like Age of Empires II Age of Kings.mid or aladdin2.mid or Curse of Monkey Island - The Barbery Coast.mid.

I eventually found a .ZIP archive with around 100,000 MIDI files. I wanted a way to search through them and share the best ones with friends. So I decided to build a site to address the shortcomings of existing MIDI sites.

And that’s BitMidi. A free way to browse and play MIDI files! ✨

If you’re curious how I built the site, there’s a section about that below. Keep reading.

Where did MIDI come from?

MIDI is an acronym that stands for “Musical Instrument Digital Interface”. It’s a way to connect devices that make or control sound — synthesizers, samplers, or computers — so they can communicate with each other, using MIDI messages.

The first synthesizer to support the MIDI standard, the Prophet-600, was released in December 1982. That’s over 35 years ago!

Prophet-600

The MIDI protocol is an old protocol even compared to other important protocols. For example, HTTP is newer than MIDI!

  • 1971 – FTP
  • 1974 – TCP
  • 1982 – MIDI
  • 1991 – HTTP
  • 1995 – SSH
  • 2001 – BitTorrent
  • 2009 – Bitcoin
  • 2015 – HTTP2

How does MIDI work?

Sound is never sent via MIDI, just digital signals known as event messages. These messages instruct pieces of equipment (or software) to start playing sound. So you need an instrument (or a set of them) to actually produce sound from MIDI event messages!

The MIDI protocol supports 128 notes (around 10 octaves), 16 channels (so 16 separate devices can be controlled) and 128 programs (which are known as “patches” or instrument voices).

How is BitMidi built?

First step, I needed to build a MIDI player in JavaScript. At first, I was determinted to write one from scratch in JavaScript and use the Web Audio API to synthesize all the instruments in code. I thought this would yield the the smallest possible JavaScript file size.

However, I didn’t really have the audio engineering skills to pull this off. So ended up settling for an approach that uses SoundFonts, which are the same as the “patches” or instrument voices described above – basically just files that contain all the possible notes an instrument can play.

BitMidi uses the instrument voices from the General MIDI sound set released by FreePats.

Then I compiled the best MIDI player written in C (libtimidity) to WebAssembly using Emscripten. I put in lots of effort to optimize the built size and include the minimal amount of code. The result of my efforts are available in the npm package timidity. It’s quite lightweight – just 34 KB of JavaScript and 23 KB of lazy-loaded WebAssembly, smaller than anything I’ve seen on any other site.

Then I put a frontend on it, so it’s easy to browse all the files. BitMidi uses all the best techniques that I know about to make it super fast and snappy. The site gets perfect 100s on all categories on Chrome’s Lighthouse Performance benchmark, which is extremely non-trivial in my experience.

I’m slightly embarrassed to admit how proud I am of this:

BitMidi's Lighthouse Score is all 100s

I’m using Preact (a small 3kb alternative to React) and a small smattering of lightweight custom code to make the site super performant. The whole site is well below 50KB of JS, which is the best way to keep a site fast.

I plan to ingest a lot more MIDI files in the future, from sources like the Geocities MIDI archive on the Internet Archive and elsewhere.

Want a new MIDI every day?

I wrote a Twitter bot at @BitMidi that tweets out a new MIDI file every day. If that sounds awesome to you, then you should follow BitMidi on Twitter.

What are some fun or interesting MIDIs?

Here are a few of my favorites:

Thanks for reading!

Feedback welcome! If you have thoughts on how to improve the site, please reach out and let me know what you think can be improved.

And please share this post and the BitMidi site with your friends that will enjoy it. ❤️ I’m hoping that you find it useful and entertaining.

(If you liked this, you might like Freedom of Speech on the Internet.)

Thanks for reading! RSS Feed Icon

Feross Aboukhadijeh I'm Feross, an entrepreneur, programmer, open source maintainer, startup founder, and mad scientist.

I build web apps like BitMidi, a free MIDI database, and Play, a music video app, and Study Notes, a site to help students study better and get into college.

I also build WebTorrent, a torrent library for the web, WebTorrent Desktop, the best desktop torrent app, and Standard JS, a JavaScript linter.

I maintain 100+ packages on npm. All my code is freely accessible on my GitHub page. If you enjoy my work support me on Patreon like these amazing supporters.

If you enjoyed this post, you should follow me on Twitter.

Or, sign up to get an email whenever I write a post: