PWA for raga practice with real-time pitch detection, tanpura drone, and Indian classical theory scaffolding

Every music practice app I've seen assumes Western tuning. That's not a minor inconvenience for Indian classical music — it's a structural mismatch. Western standard tuning divides the octave into 12 equal semitones (12-TET). Indian classical music uses 22 shrutis: microtonal intervals that don't map cleanly onto those 12 slots, and that carry specific emotional and theoretical weight in raga grammar. When you're learning bansuri — bamboo flute, an instrument that lives and dies by intonation — an app that can only hear you in 12-TET is worse than useless. It actively teaches you the wrong thing.
I play bansuri myself, on and off. Not seriously enough to call myself a musician, but seriously enough to know what a student needs that existing tools don't give them. So I built the tool I wanted.
The tuning decision was the hardest architectural call. pitchy, the FFT-based pitch detection library I used, returns a frequency in Hz. Converting that to a Western note name is a one-liner — the formula is well-documented. Converting it to the nearest shruti in just-intonation requires a reference frequency (the Sa, the tonic), an understanding of the raga's swar set, and a mapping table from theoretical shruti ratios to actual Hz values at that reference pitch.
I built all of that from scratch. The shruti table lives as a typed constant. The pitch detection pipeline computes distance from each candidate shruti and surfaces the nearest match against the active raga — so the app doesn't just hear "you played a komal Re," it hears "you played a komal Re in Bhairav at 6 cents flat." That's the level of feedback a serious student needs.
The tanpura drone is the other piece Western apps simply don't have a concept of. A tanpura is a four-stringed instrument played continuously to provide a harmonic reference — when you're improvising in a raga, you always have the drone anchoring you to Sa. Tone.js let me synthesise this: four oscillators with configurable tuning, resonance, and decay, producing something close enough to the real thing to be musically useful for practice.
The entire project — 15,278 lines, 16 test suites, a gamified six-level curriculum across 10 ragas and 14 alankars, a Jugalbandi call-and-response game, 22 achievements, bilingual UI in English and Hindi — was built in a single day. Two commits, 31 minutes apart, on March 18, 2026.
That's only possible with a clear picture of the architecture before you write the first line. I knew the stack before I started: Next.js 16 App Router for the shell, pitchy for pitch detection, Tone.js for synthesis, Zustand persisted to localStorage for session state, Serwist for the PWA service worker. I knew the data shape: ragas as typed objects with their aroh, avaroh, and swar restrictions. I knew the UI structure: a practice screen, a progress screen, an achievements screen.
Zero backend was also a deliberate choice, not a shortcut. Indian classical music practice is fundamentally a solo activity — you and the tanpura, you and your riyaz. There's no social layer that needs a server. Everything that needs to persist (practice history, level progress, achievements) fits in localStorage. Offline-first via Serwist means the app works in a basement studio with no signal, which is where a lot of practice actually happens.
15,000 lines in one day means the architecture is sound and the features work, but the polish layer is thin. The pitch detection latency is acceptable but not imperceptible on lower-end devices. Some of the raga exercises are structurally correct but not pedagogically sequenced the way an actual ustād would sequence them — I know enough about Indian classical theory to build the scaffolding, not enough to replace a teacher. The gamification is genuine (the achievement system tracks real practice milestones) but the XP curves are guesses, not data.
I'd rather be honest about this than present SwarSadhna as a finished product. What it demonstrates is that I can take a domain with real theoretical depth — one that most developers would wave away as too niche or too complex — look at what the default tools offer, decide they're not adequate for the actual use case, and build the evidence for a better approach in a single focused session.
The gap between Western music tooling and Indian classical theory isn't going away on its own. Someone has to build across it. I did, in a day.
Expo 50 app with expo-router, Tamagui, NativeWind, Zustand, and Reanimated 3
Full-stack React Native fashion app with GPU canvas product rendering, AI background removal, and Turborepo monorepo
AI writing room for Indian television
Did this resonate?