Quinton Nistico

Back to portfolio
Live Product

VampJam

A practice tool for improvising musicians. Describe what you want to play over — key, tempo, feel — and get a backing track built for it, then loop a phrase, drop the tempo, or fix a chord the model got wrong without leaving the player.

Visit VampJam.com
Role
Sole designer and engineer
Launched
April 2026 — live, with paying subscribers
Scope
~30 routes · live billing · 3 external audio services
Stack
Next.js · React 19 · TypeScript · Supabase · Stripe · Cloudflare R2

What this page is

VampJam is roughly 30 routes, live billing, and three external audio services. I could list what's in it and you'd learn nothing about how I think, so this covers three decisions instead — the ones where the obvious answer was available and I didn't take it.

The hard part was never generating audio. It was keeping a deep set of controls calm enough to use mid-song, with a guitar in your hands.

Three decisions

Each one in the same shape: the fork, what I turned down, why, and what it cost.

01

Two doors into generation

The fork

Most products in this space ships one freeform prompt box — Suno, Udio, all of them. I shipped two: Open Prompt for exploring, Quick Mix for when you already know what you want.

What I rejected
  • A single prompt box. The industry default, and it treats musical facts as prose.
  • A wizard. Too many steps for something you do over and over.
Why

Key, tempo, and scale aren't preferences — they're facts, and prose is a lossy channel for facts. A player who knows they want A minor, 90bpm, blues shuffle, no guitar shouldn't have to write a paragraph and hope the model infers it.

Negation is the clearest case. You can't reliably say "no guitar" to a generative audio model in prose — it hears the word and gives you a guitar. Structured input makes it deterministic, which is what the No Guitar Mode control actually is.

Both paths converge on one prompt builder, so the surface splits but the system doesn't.

The cost I accepted

Two doors means a first-time user has to choose before they've made anything. I took that trade, because exploring and knowing exactly what you want are genuinely different states and one box can't serve both.

02

Fifteen tools, one player

The fork

A practice player needs a metronome, tuner, EQ, transpose, tempo trainer, loop markers, stems, recording, and a timer. Everything on screen at once is a cockpit. Everything behind menus is unusable mid-song.

What I rejected
  • A settings page. Wrong model entirely — you adjust these while the audio is playing, not before.
  • Expanding accordions. They push the waveform around while you're trying to use it.
Why

The toolbar stays visible so the capability is legible, but only one panel opens at a time and it opens in place. The player never moves. The audio never stops.

You're adjusting an instrument while it's playing, not navigating an app. That's the whole distinction, and layout stability is what carries it.

The player persists across all 30 routes, so leaving the page doesn't mean leaving the track.

The cost I accepted

One panel at a time means you can't watch the tuner and the metronome together. Almost nobody does — and the layout holding still is worth more than that edge case.

03

Designing around a model that's wrong

The fork

Chord detection runs about 80% accurate. Three options: hide it until the models get better, show it and hope, or show it and let people fix it.

What I rejected
  • Waiting for accuracy. It isn't coming soon — chord extraction from audio is genuinely hard.
  • Confidence scores. A percentage next to a chord name is noise to a guitarist.
Why

Musicians can hear a wrong chord instantly. They don't need to be told the model is unsure — they already know. So the interface's job isn't to be right, it's to be correctable in one click.

Overrides persist per track in the database, so a fix is permanent rather than a session-long annoyance.

Two views, because reading a progression and playing it are different jobs: a chord chart for one, a fretboard timeline for the other.

The cost I accepted

Shipping visibly imperfect output, which most products won't do. The alternative was shipping nothing — and a wrong chord you can fix in one click beats no chords at all.

When the platform decided the feature

The clearest case of an engineering constraint reshaping a design, rather than just complicating one.

The constraint

Routing an audio element into the Web Audio graph is permanent — one call and there's no undoing it for that element's lifetime. On iOS, where every browser is WebKit underneath, that kills playback rate control and desyncs pause.

So opening the EQ panel once broke transpose, the tempo trainer, and pause, with no recovery short of a reload. Nothing in the UI suggested a connection between those features.

The design consequence

Transpose ships as two modes rather than one. Quick mode uses the native playback rate — instant, free, and pitch drags tempo along with it. True pitch shift is computed server-side, preserves tempo, costs a round trip, and is gated to paid tiers because it costs real money to run.

That's a pricing boundary and a feature model that both exist because of a browser behaviour. Every surface touching the audio graph is guarded, and iOS gets an explanatory card where the EQ would be — the honest version of a feature that can't work there.

The detail that catches people

Modern iPads report themselves as desktop Macs. The obvious device check passes them straight through into the broken path, so the guard has to test for touch support as well as platform — otherwise it silently misses every iPad shipped in the last several years.

What I got wrong

Generation costs tokens, and generation sometimes fails — so failures refund automatically. For one feature, that refund had silently never worked. The call passed a parameter the database function didn't have, and nothing checked the error that came back.

It survived months of testing because the interface looked correct the whole time. There was no error state to notice. Users were quietly losing tokens on failed jobs and I had no signal at all.

I found it by comparing that call against the others doing the same thing and noticing one disagreed with its neighbours. That's now how I audit anything that touches money — not by testing behaviour, which looked fine, but by checking whether every call site agrees. The odd one out is usually the bug.

VampJam — the player interface

Designed, built, and shipped solo. Live at vampjam.com.

Try it