Open-source project
feross/bitmidi.com avatar
feross/bitmidi.com

bitmidi.com is a web MIDI player with an import pipeline and a MySQL catalogue

🎹 Listen to free MIDI songs, download the best MIDI files, and share the best MIDIs on the web

619 stars55 forksJavaScriptLicense varies

At a glance

What is it?
bitmidi.com is the full stack behind a site that plays and shares MIDI files, with a Node.js server, a Preact front end, a MySQL catalogue and a command line importer that reads a folder of MIDI files. It suits a developer who wants to run or extend a working MIDI site rather than embed a player, and it is a server application, not a library.
Who is it for?
bitmidi.com fits a developer who wants a running MIDI archive to study, extend or self host, since the repository contains the server, the front end, the migrations and the importer rather than a documented API you have to reassemble. It does not fit a product that only needs to play a MIDI file in a page, since the useful pieces here are the catalogue and the site, and it does not fit a deployment without MySQL and ImageMagick style system tooling.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 13 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The archive is the product, not the player

bitmidi.com is a website for listening to free MIDI songs, downloading MIDI files and sharing them, and the project description calls it the wayback machine for old-school MIDI files.

The example list in the documentation is the clearest statement of what the catalogue contains: a Backstreet Boys MIDI, Beethoven's Moonlight Sonata, Camptown Races, an overworld theme from Golden Sun, Dearly Beloved from Kingdom Hearts, the Legend of Zelda overworld, two Michael Jackson tracks, a Passenger track, three Pokemon themes, and two Red Hot Chili Peppers pieces.

So this is a curated archive with a player attached, rather than a general purpose MIDI playback library. Each entry has its own page with a URL slug, and the site is the way to find and share a specific file.

For an engineer, the interesting part is the machinery behind that catalogue rather than the catalogue itself. The repository is the complete site: server, front end, database schema, migrations, import tooling and deployment configuration. If you want to understand how a MIDI archive is built, or run your own, this is a working reference implementation with the decisions still visible in the code.

The homepage is bitmidi.com and the last push was on 2026-10-10, with no GitHub releases, so this is a continuously worked on application rather than a versioned package.

Preact on the front end, Babel and Browserify on the build

The package.json tells you the stack. The Babel configuration compiles JSX with the automatic runtime and an importSource of preact, so the components are Preact components rather than React ones, with a smaller runtime shipped to the browser.

The Babel plugin list is period specific: transform-modules-commonjs, proposal-optional-catch-binding, transform-react-jsx, proposal-object-rest-spread with useBuiltIns, and proposal-class-properties in loose mode. The build pipeline is Browserify with the babelify transform, and the browserslist targets the last two versions of Chrome, Android Chrome, Firefox and Safari, the last two iOS Safari versions and the last Edge version.

There is a browser field in package.json that swaps modules for the browser build, which is a neat solution to the server-client split: the secret file becomes false so nothing server side leaks into the bundle, the API module is replaced by a browser-specific one, and the server start module is replaced by a browser entry point.

json
  "browser": {
    "./secret/index.js": false,
    "./src/api/index.js": "./src/browser/api.js",
    "./src/server/start.js": "./src/browser/index.js"
  },

The same package.json declares a browser field for the secret module, which is also why the sample secret file exists as a separate step in the setup. The repository layout backs this up: src/ for the application, static/ for assets, migrations/ for the database, tools/ for the importer and other scripts, and secret/ for credentials that must not be committed.

MySQL, knex migrations and a credentials file you have to edit

The database setup is the part of the documentation that gives the most precise instructions, and it is also where a new contributor will lose time if they skip a step.

The first step is to copy the sample secret file.

bash
cp secret/index-sample.js secret/index.js

Then run a local MySQL server on port 3306 and create a database named bitmidi.com. The documentation emphasises changing the credentials in secret/index.js to match, and also changing the MySQL version setting if yours differs from the one specified. For an older MySQL there may be a need to add an insecureAuth: true option under db.connection.

That last detail is a small time capsule. It reflects the era in which MySQL changed its default authentication plugin, and it tells you the project has not been modernised in that respect.

Migrations are run with knex through the npm script.

bash
npm run knex -- migrate:latest

The migrations directory sits at the repository root, so the schema history is versioned with the code. Deployment configuration is present too, with nginx.conf and supervisor.conf at the root, which tells you the intended production topology is nginx in front of a supervised Node.js process.

The package.json also configures ava with @babel/register required and babel disabled, meaning the test runner compiles on the fly rather than through a separate build step.

The importer takes a folder of MIDI files off your disk

To see the site with content, you need MIDI files on disk, and the documentation links two collections for that: a large one posted in a Reddit thread and smaller ones from a site hosting Bach MIDI files.

The import is a single command run from the project root.

bash
node -r @babel/register tools/import.js <path-to-folder-with-midis>

The @babel/register flag is there because the tool is written in the same modern JavaScript the rest of the project uses, and Node cannot run that syntax directly without the runtime transform.

So the workflow is: gather a folder of MIDI files, point the importer at it, and the database catalogue is populated. That is a pleasant piece of design, because the alternative would be hand inserting rows.

The system dependencies for that pipeline are worth noting as well. GraphicsMagick is needed, with install commands given for Ubuntu and MacOS, and there is a requirement for the webp tooling that imagemin-webp pulls in through the cwebp-bin package, with the note that Ubuntu needs libxi6 and libglu1 while MacOS has no equivalent step. The webp dependency is for converting and serving artwork efficiently, which is the kind of detail that only shows up in the documentation once someone has already hit it.

Running the server, and the watch mode for development

Two commands run the site locally.

bash
npm run build
npm start

And there is a separate script for automatic rebuild and restart during development.

bash
npm run watch

Having both a build step and a start step in a project that also runs through Babel at import time is worth pausing on. The Babel register hook is used for the importer, and the AVA test configuration requires @babel/register too, so the codebase is written in modern JavaScript that is transformed at runtime in the tooling paths, while the browser bundle is built ahead of time by Browserify and babelify.

The repository root also holds a .npmrc, a .travis.yml for continuous integration, a .gitignore, and a test directory.

The version field in package.json is 1.0.0 and the name is bitmidi.com, which tells you the package is named after the site rather than published as a reusable module. Combined with the browser field and the absence of any library entry point, the intent is clear: this is an application repository.

Licensing and what the repository does not claim

The licence information is thin, and that is worth stating plainly rather than filling the gap. The repository metadata does not classify the licence, while the documentation's license section contains only a copyright line naming Feross Aboukhadijeh. There is a LICENSE file at the root of the repository, so the terms are there to be read rather than summarised here.

That matters if you plan to run this yourself with a real catalogue. A MIDI file is a composition, and the pieces in the example list are commercial songs, from Backstreet Boys to Michael Jackson. The site is a catalogue of shared files, and how the project handles the rights in those files is a question for the rights holders and the project's own terms rather than something the documentation answers.

The last push was on 2026-10-10 and the repository is not archived, so the site is actively worked on. There are no GitHub releases, so there is no version history to consult, and the version field stays at 1.0.0.

For a developer, the practical reading is that this is a working reference implementation and a live site, and that the interesting engineering is in the pipeline, the migrations and the build, rather than in anything you would import into your own product.

Editorial conclusion

bitmidi.com fits a developer who wants a running MIDI archive to study, extend or self host, since the repository contains the server, the front end, the migrations and the importer rather than a documented API you have to reassemble. It does not fit a product that only needs to play a MIDI file in a page, since the useful pieces here are the catalogue and the site, and it does not fit a deployment without MySQL and ImageMagick style system tooling. Before adopting it, check that you can provide MySQL on port 3306 and a database named bitmidi.com, adjust the credentials in secret/index.js and the MySQL version setting the setup notes mention, and confirm the licence terms in the LICENSE file since the repository metadata does not classify them.

Frequently asked questions

How do I set up the bitmidi.com database locally?

Copy the sample secret file with cp secret/index-sample.js secret/index.js, run a local MySQL server on port 3306, create a database named bitmidi.com, and update the credentials and MySQL version in secret/index.js. Then run the migrations with npm run knex -- migrate:latest.

How do I import my own MIDI files into bitmidi.com?

Put the MIDI files in a folder and run node -r @babel/register tools/import.js with the path to that folder from the project root. The site needs that folder populated to show content.

What system dependencies does bitmidi.com need?

GraphicsMagick, with install commands given for Ubuntu and MacOS, plus the webp tooling from the cwebp-bin package, which on Ubuntu needs libxi6 and libglu1. The documentation lists no MacOS equivalent for that second step.

Is bitmidi.com a MIDI library I can add to my project?

No. It is the application behind the site of the same name, with the server, the Preact front end, the MySQL schema and the import tool in one repository. The package is named bitmidi.com at version 1.0.0 and is not published as a reusable module.

Official sources

  1. feross/bitmidi.com on GitHub
  2. Issues
  3. Project website
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/feross-bitmidi-com.svg)](https://hysenlabs.com/projects/feross-bitmidi-com)

Was this useful?