An open-source, web-based guitar tuner that uses the YIN algorithm and your device's microphone to detect pitch in real time.
Currently Sonance only supports standard tuning. More tunings will be added in the future!
| String | Note | Frequency |
|---|---|---|
| 6th | E2 | 82.41 Hz |
| 5th | A2 | 110.00 Hz |
| 4th | D3 | 146.83 Hz |
| 3rd | G3 | 196.00 Hz |
| 2nd | B3 | 246.94 Hz |
| 1st | E4 | 329.63 Hz |
- React 19 + TypeScript
- Vite (build tool)
- Tailwind CSS v4 (styling)
- pitchfinder (YIN algorithm for pitch detection)
- Web Audio API (microphone input + audio analysis)
- Node.js 22+
- Docker (optional, for containerized hosting)
npm install
npm run devOpen http://localhost:5173 and click Start Tuning.
| Command | Description |
|---|---|
npm run dev |
Start dev server with HMR |
npm run build |
Type-check and build for production |
npm run preview |
Preview the production build |
npm run lint |
Run ESLint |
Build and serve the production app via nginx:
docker compose upOpen http://localhost:3000.
To rebuild after code changes:
docker compose up --buildsrc/
main.tsx Entry point
App.tsx Root component (start/stop + tuner display)
index.css Tailwind CSS import
lib/
pitch.ts YIN detector, frequency-to-note mapping, cents calculation
hooks/
use-tuner.ts Microphone access, AudioContext, real-time detection loop
components/
tuner-display.tsx Note display, needle gauge, cents bar, tuning status
- User clicks Start Tuning -- microphone permission is requested
- Audio streams into an
AudioContextviagetUserMedia - An
AnalyserNode(fftSize 4096) extracts time-domain samples as aFloat32Array - The YIN pitch detection algorithm identifies the fundamental frequency
- The closest standard tuning note is found using cents offset:
1200 * log2(detected / reference) - The UI displays the note, frequency, cents deviation, and whether the string is flat, sharp, or in tune
- In tune: within +/- 5 cents
- Close: within +/- 15 cents (yellow)
- Off: beyond +/- 15 cents (red)
Contributions are welcome. Here's how to get started:
- Fork the repository
- Create a feature branch:
git checkout -b feat/your-feature - Make your changes
- Run lint and build checks:
npm run lint && npm run build - Push to your fork and open a pull request
- Keep PRs focused on a single change
- Ensure
npm run buildpasses before submitting - Follow the existing code style (ESLint config is included)
- No unused imports, variables, or dead code
MIT
