Project: Decimal - a Binaural Beats generator
It’s been a while since I indulged in a pure piece of R&D, and the list of tools I’ve been keen to play with has grown pretty lengthy. I finally managed to carve out a week to get down to some serious experimentation and the result is Decimal, a free Binaural Beats generator delivered as a PWA.
I’ve been using Binaural Beats ever since I heard about them in the Huberman Lab episode on concentration, Focus Toolkit: Tools to Improve Your Focus & Concentration. I’ll add that I’ve also found them incredibly effective as a sleep aid.
While the concept works for me, the existing apps are generally pretty poor; ad-laden and lacking in terms of UX. With Decimal, I wanted to deliver an app that users can love, without the ad and tracking bloat that comes with so many apps. My main goals were:
- Exceptional speed and performance
- Joyful to use - nicer than any existing apps
- No invasive ads or tracking
I hope I’ve achieved all three. The end result is what I’ve started to refer to as a toy; it’s fun to use, singular in purpose and has no intention of delivering any commercial outcomes. A true “small web” project.
The biggest epiphany for me was using Nanostores to share state between disparate React components - like the main player and persisted mini player in the header. Nanostores make this super easy, and the resulting code is far clearer than the eqivalent would be with a Provider/Context hook. I’ll definitely be using this approach in future.
The tones themselves are generated with the Web Audio API, so you can switch from the suggested presets to entirely custom frequencies. As part of my three goals above - I was eager to get lock screen controls functional on mobile. The Media Session API, however, doesn’t have any awareness of Web Audio instances, so I resorted to a hack: playing a looping mp3 of silence, and then binding to the Media Session callbacks for that
<audio /> to control the Web Audio output.
All of this is made feasible with Astro’s
<ViewTransitions />. I can just append
transition:persist to any component to have it persist in the client between page navigations - so there’s no loss of audio playback etc as you navigate around. You get some fantastic transitions too - with no implementation overhead.
Astro is increasingly looking like a framework/build tool I can go all in on; the life cycle is super intuitive and ability to drop in piecemeal UI framework components is incredible. The default 💯 page speed scores are pretty compelling, and because the app compiles to static and generates the audio entirely in the client, it costs next to nothing to run.
Tech aside, I’ve also done some experimentation with using GPT 4 and DALLE-3 to generate blog posts that I hope will deliver some educational and actionable information for new comers to binaural beats. I really struggle to pen that sort of content myself, so this was a novel way to overcome a writer’s block; hopefully some craftmanship at the the prompt level pays off in the output. These posts will be rolling out on the blog over the next couple of months.