Case study
I built my own bass practice tool, and I finished it.
A practice tool I built for myself in React: generative backing tracks synthesized live with Tone.js, and reflective feedback wired in through the Claude API. No client, no deadline. Just a real product, built end to end, because I wanted to use it.
Receipts
- Skills proven
-
- React product development
- Generative audio with Tone.js
- Claude API integration
- Wiring live third-party services
- Shipping a product end to end
- Stack
-
- React
- Tone.js
- Claude API
- Quality
-
- User-initiated audio (no autoplay)
- A real product, not a prototype
- Two live services in one interface
- Outcomes
-
- Built for daily practice
- Live audio + an LLM in one product
- Personal project · creative range
On the docket
- 01 Why I built my own practice tool
- 02 Wiring live services into a real product
- 03 Creative range, and caring about the finish
Bass Face is a personal project, and that's the whole point. I play bass and gig regularly, so I know exactly what I want out of a practice session. Instead of settling for a metronome and a backing-track playlist, I built the thing I wished existed. And because no one was asking for it, no one was around to talk me out of sweating the finish.
Step 01
Why I built my own practice tool
Practicing bass well takes two things most tools give you only one of: something to play against, and an honest read on how it went. Backing tracks are static: the same loop every time, in the same key, at the same tempo. And nothing tells you what to work on next except your own memory of a session you were busy playing through.
So I built Bass Face for myself, as a real React product rather than a weekend throwaway. Building for an audience of one is a strange kind of freedom: there was no spec to satisfy and no deadline to cut against, which meant the only thing deciding when it was “done” was whether I actually wanted to open it every day. That's a higher bar than most briefs set.
What it needed
Something to play against
Backing tracks that change instead of repeating, generated live, so practice never collapses into muscle memory of one fixed loop.
What it needed
An honest read
Reflective feedback on a session, so the next one has a direction instead of starting from a blank page every time.
Step 02
Wiring live services into a real product
Bass Face leans on two live services, each doing something a static app can't. Tone.js synthesizes the backing tracks in the browser in real time. This is generated audio, not a file being played back, so the accompaniment can shift instead of looping. Audio is always user-initiated: you press play. That's both the natural interaction and the right accessibility default: nothing blasts out of the speakers the moment the page loads.
The second service is the Claude API, wired in for reflective feedback, turning a practice session into a short, useful read on what to work on next. The interesting engineering isn't either service on its own; it's making real-time audio synthesis and an LLM live together in one coherent interface, with the latency, state, and failure modes of both handled gracefully. That integration work is exactly what product engineering is.
Tone.js · generative backing tracks
Audio synthesized live in the browser, user-initiated by design: practice accompaniment that changes instead of repeating.
Claude API · reflective feedback
An LLM wired into the practice loop to reflect a session back and point at what to work on next.
The hard part isn't either service alone. It's making real-time audio and an LLM feel like one finished product.
Step 03
Creative range, and caring about the finish
Bass Face covers a lot of distance for a personal project: live audio synthesis on one side, an LLM integration on the other, and a real interface holding both together. That range (comfortable wiring up DSP-style audio one moment and a language model the next) is the part I'm proud of. It's the same instinct that lets me move across a stack instead of staying in one lane.
And because I built it for myself, nothing forced me to cut the last ten percent: the empty states, the play/stop interaction, the moment when there's nothing to reflect on yet. That's the same finish I bring to the products I ship for teams. A personal tool is just the clearest place to show it, because there's no one else to blame for the parts that aren't done.
Creative range
Real-time audio and an LLM in one build: comfort moving across very different parts of a stack.
Live services, wired well
Third-party services integrated into a coherent product, not bolted on as a demo.
A finished feel
The last ten percent (empty states, interactions, defaults) treated as the point, not the afterthought.
Product engineering
I build complete products, end to end.
Bass Face is what I build when no one's asking: live audio, an LLM, and a finished interface, wired together for the fun of it. The same instinct shows up in the products I ship for teams. Let's talk.