Music Library
I built a personal archive of probably every concert and work I've ever performed. It lets me see the repertoire I've accumulated over a lifetime and revisit when, where, and with whom I played it.
Table of Contents
Why I Built It
I had always wanted one big list of all the repertoire I had performed. The information existed, but it was scattered across a lifetime of artifacts. I had paper programs from concerts I played as a kid and digital programs, emails, and calendar entries from more recent years. None of those sources could show me the whole picture.
At some point, I went home to my dad's house in Oregon, found the box of concert programs I had saved since childhood, and started entering them into Obsidian. I was already a heavy Obsidian user, and its properties, frontmatter, and links between notes made it possible to record more than a flat list. A concert could point to the works on its program, the group that played them, the conductor, and the venue. For the first time, seeing probably every work I had performed felt possible.
The idea initially grew out of anti-performances, my Instagram account about orchestra life. I imagined extending it with the photos, audio, and other media attached to each concert. As I worked on it, though, the program information became the center. The lasting value was not any one photo; it was the connected record of what I played. The project became the Music Library.
I love seeing the size and shape of that repertoire, but the archive is also a way back into its context. I can find the last time I played a piece, where the concert happened, and who was there. Opening an old concert often takes me back to the person I was and the life I was living when I played it.
Building with AI
Once I had a useful amount of information in Obsidian, I realized that the vault was just a collection of files underneath. If I could parse those files, the same notes I wrote for myself could power a website. I knew what I wanted the archive to express, but building every type, parser, query, and page by hand would have made it a much bigger project.
This was one of the first projects where working with Cursor made a personal idea suddenly feel feasible. I was using Claude 3.5 Sonnet in Cursor, and the experience was less like asking for a finished app and more like shaping one through a conversation. I could point Cursor at the templates in my vault and ask it to turn the concepts already there into TypeScript types, data-processing code, and a familiar Next.js structure. Then I could run what it made, see what was wrong or missing, and steer the next pass.
That translation from templates to software was the moment the potential of AI-assisted building clicked for me. The model could hold a lot of mechanical context at once and move quickly across layers of the app. It made experiments cheap enough that I could discover the product while building it instead of fully specifying everything up front.
It did not replace the difficult judgment. Cursor did not know what a Concert or a Work meant in my archive, which relationships mattered, or whether a page felt useful to a musician. I supplied the records, the domain knowledge, the direction, and the taste; Cursor accelerated the implementation. The most important work was still thinking carefully about the nouns in the system and how they connected.
Connected Notes
The Music Library's source material is a set of human-authored Markdown
notes in a standalone Obsidian vault at ~/Obsidian/Music Library. That vault
is the source of truth: it is where the system was originally designed, and a
copy also lives in my larger Megavault setup. The connections between the notes
are what make the archive work.
A Concert sits at the center of the model. It has a date and belongs to a season. It links to a group, a venue, one or more conductors, and every work on the program. A Work links to its composer and, in the other direction, to every concert where I performed it. Following those links answers the questions I actually care about: When did I last play this? Which orchestra was it with? What else was on that program? Have I performed another work by this composer?
There are notes for composers, conductors, groups, venues, seasons, rehearsals, and sheet music, too. They are not independent database rows that I maintain in an abstract admin screen. They are readable notes I can connect with Obsidian links and properties as I write. The structure is deliberate, but it stays close to the way I naturally think about a concert program.
Authoring usually starts with a Concert. If the group is new, I create the
Group note first, because the Concert template selector requires an existing
group. I then create the Concert shell from the template, add any missing
referenced entities in dependency order (a Composer before its Work),
and return to the Concert in the same session to fill in Obsidian Properties and
wiki-links. Per-work soloists, conductors, or movements go under
## Program Details.
A concrete example is the February 23, 2025 Brooklyn Symphony Orchestra concert: create the Concert shell, add Brooklyn Symphony Orchestra, Brooklyn Museum, Nico Olarte-Hayes, and each work on the program (creating composers and works as needed), link them through Properties, then record Stuart Sankey's double-bass solo on the Carmen Fantasy in Program Details. Dataview queries in the vault surface reverse views from those same linksโevery concert for a work, every work by a composerโwhile the public site derives its pages and filters from the identical relationships when I run the generator.
That connected-note model is also the boundary between my work and the generated site. I decide what the objects mean and maintain the source material; the software follows those relationships outward to create the archive people can browse.
From Notes to the Site
The publishing pipeline is intentionally simple. I run
npm run generate-music-db -- <vault-path>, which invokes
generate-database.ts against the music notes in the standalone Music Library
vault (or another path I pass). The script reads the Markdown and frontmatter,
resolves the Obsidian links, and produces separate JSON files for concerts,
works, composers, groups, venues, and the other entity types.
The Next.js app imports that generated data and turns it into the pages under
/music. The index pages can sort composers and works by concert count. A
concert page can assemble its program, venue, performers, map, and optional
Spotify link from the same relationships I authored in Obsidian. Faceted
filters work because seasons, groups, venues, conductors, and composers are
connected consistently instead of trapped in program-shaped blocks of text.
The private notes themselves are not published. The generator selects the structured information the site needs and emits a static snapshot that can be built and deployed with the rest of this site. That separation lets Obsidian remain my writing environment while the public Music Library gets predictable, queryable data.
๐ See the generate scripts on GitHub
Browsing the Archive
I do not really think of the Music Library as a tool I sit down to use. It is more like a place I browse and explore. I might open a work and discover that I have played it more often than I remembered, or move from a concert to a venue to see everything else I performed there. Filters let me narrow the history by season, group, conductor, venue, or composer, but the point is usually curiosity rather than productivity.
The counts and cross-links make the scale of a performing life visible in a way that a stack of programs never could. They also make the archive associative. Looking up a piece can lead to an old orchestra, another work on the same program, or a concert I had not thought about in years. The record is factual, but browsing it is personal.
There are practical corners of the library. Upcoming concerts have an ICS calendar subscription. The bucket list gives me a place for repertoire I still hope to play. Concert pages can include ticket or calendar links, venue maps, and Spotify recordings. Those features make the archive richer, but they are not why I keep returning to it.
I return because an old program is more than a list of pieces. It remembers a place, a group of people, and a particular moment in my life. Entering all those paper programs gave me the complete repertoire list I had always wanted. Connecting them gave me a way to wander back through it.
๐ Browse the live Music Library
Originally posted: 2026-07-16
Last updated: 2026-07-16