Turn spoken audio into study material. Voice-to-Note transcribes an audio clip with
OpenAI Whisper, then uses a GPT chat model to convert the transcript into
flashcards (Front::Back pairs) you can review in the UI.
Hackathon project. The backend is functional; the frontend is mid-refactor and does not currently build (see Status below).
TODO — add a screenshot once the frontend build is fixed. The intended UI is a Home page (record/upload audio) and a
/flashcardsreview page.
- Audio → transcript —
POST /api/transcribeaccepts base64 audio, sends it to the Whisper API (whisper-1), and returns the transcript. - Transcript → flashcards — the transcript is passed to a GPT chat model
(
gpt-3.5-turbo) that returns shortFront::Backflashcard strings, parsed into structured cards. - No-key demo mode — if no OpenAI key is configured, the transcribe endpoint returns a canned demo transcript and sample flashcards, so the flow can be demonstrated without credentials.
- Local persistence — generated notes and sentences are saved to local JSON files
(
notes.json,local_sentences.json) and served back via/api/notesand/api/flashcards.
| Layer | Choices |
|---|---|
| Frontend | React 19, Vite 7, React Router 7 |
| Backend | Node.js, Express 5, node-fetch, form-data |
| AI | OpenAI Whisper (transcription) + GPT chat (flashcard generation) |
| Method | Route | Description |
|---|---|---|
POST |
/api/transcribe |
{ audio_base64, filename?, mimetype?, save? } → { transcript, generated } |
POST |
/api/process-text |
{ text } → flashcards parsed from raw text |
GET |
/api/notes |
Returns saved notes |
GET |
/api/flashcards |
Returns generated flashcards |
Prerequisites: Node.js 18+ (the backend uses global fetch/FormData).
cd backend
npm install
node server.js # http://localhost:3001Without an API key it runs in demo mode. To enable real transcription, set an OpenAI key (see Environment variables).
cd frontend
npm install
npm run dev # Vite dev server (once the build issues are resolved)Backend .env (gitignored — do not commit). Variable names only; the server
accepts any one of:
| Variable | Used for |
|---|---|
OPENAI_API_KEY (preferred) / OPENAI_KEY / OPENAI |
OpenAI Whisper + chat completion access |
This project is in progress. Two issues block the frontend from building:
- Merge conflict in
frontend/package.json— the file still contains<<<<<<< HEAD … ======= … >>>>>>> frontendmarkers from an unresolved merge and is not valid JSON. It needs to be resolved (keep thevoicetonotesapp config with React/Vite deps). - Missing component —
frontend/src/App.jsximports./pages/Home, but nopages/Homefile exists insrc/(onlyheader.jsx,flashcard.jsx,flashcardPage.jsx). The Home page needs to be added or the import repaired.
The backend has no known blockers and runs standalone.
voice-to-note/
├── backend/
│ ├── server.js # Express API (transcribe, notes, flashcards) + demo fallback
│ ├── processing.js # Transcript → flashcard parsing + local JSON persistence
│ └── harvard.wav # Sample audio for testing
└── frontend/
└── src/
├── App.jsx # Router: / and /flashcards
├── flashcardPage.jsx # Flashcard review page
├── flashcard.jsx # Flashcard component
└── header.jsx
- Graceful degradation. The transcribe endpoint detects a missing API key and falls back to a demo response — a deliberate choice so the project always demos, even on a judge's machine with no credentials.
- Tolerant flashcard parsing.
parseLineToFlashcardaccepts several formats (Front::Back,Front: Back,"X is Y") so messy model output still maps to a usable card.
No license file is present; treat as all rights reserved unless one is added.