July 7, 2026
It's truly hard to say how special of a time in my life this was. I had the benefit of being aware of it at the time, which is not something granted to most of us during these experiences. Yes, I treated it like way too much of a party and didn't grow as much as a musician as I probably could've, but I can't count the number of times someone came up to me and said, "This is the only place I get to play with other people. Thanks for doing this." I still damn near tear up thinking about that.
Archiving the PandaJAM from HamsterDAM
For five years I ran a weekly open jam: Wednesday nights at Sticks & Stones in Hawthorne, New Jersey. Anyone could walk in, plug in, and take the next tune. We recorded damn near every one. The jam's over now, but the tapes aren't — and this site is where they live.
Every week's recording went up on the Internet Archive under the band's name, so the audio has a permanent home that isn't my hosting bill or some platform that might fold and take it all with it. The site is the front door to that pile: a browsable index of every jam, newest first, with the Archive's own player embedded so you can listen without leaving.
One call, then get out of the way
The archive stores no data of its own — everything lives on archive.org. When the page loads it makes exactly one
request: a single advancedsearch query for
creator:"PandaJAM From HamsterDAM", sorted newest-first, asking for each jam's identifier, date, and
description in one shot.
That last field is the whole trick. Pulling the descriptions along in the same query means selecting a jam needs no further network round-trip — the text is already in hand, keyed by identifier, ready to drop in the instant you click. So the sidebar renders as the results stream in, instead of firing a metadata request per jam and waiting. One fetch, and everything after it is just DOM.
q = creator:"PandaJAM From HamsterDAM"
fl[] = identifier, date, description
sort = date desc
rows = 500
Hash routing, no framework
Each jam is a URL fragment — # plus its Archive identifier — so the browser's back button and a
shared link both work without a router library. Clicking a jam swaps in an
archive.org embed with ?playlist=1, so the whole
night plays through; clearing the hash drops you back to the home view and its
YouTube playlist. That's the
entire navigation model — a hashchange listener and about ten lines.
It used to be Bootstrap
The first cut leaned on Bootstrap and the wall of markup that comes with it. I tore that out and rewrote the whole
thing vanilla — hand-written HTML, one small main.js, plain CSS. No build step, no dependencies, nothing
to keep patched. For a site whose only job is to list some recordings and embed a player, a framework was weight with
no payoff; it loads faster now, and I can read every line of it. That matters more once a thing goes from
"I touch it every week" to "I touch it twice a year." The
source is on GitHub.
It's served from GitHub Pages on its own domain, which for a static archive costs nothing and won't quietly go dark the year I forget it exists.
The room's gone and the amps are packed up, but the recordings are still up, still browsable, still one click from playing. Every Wednesday we made a little noise in Hawthorne — this is where it keeps.