Real-time meeting transcription & AI-powered note-taking — 100% local, 100% private
A macOS desktop app for real-time meeting transcription (Teams, Meet, Zoom...) with automatic summary and key point generation. Everything runs locally — no external APIs, no data sent to the cloud.
- Real-time transcription — Simultaneous mic + system audio capture (Whisper Turbo)
- Local AI — Summaries, key points, action items via Ministral 3B
- Contextual chat — Ask questions about your past meetings
- Bilingual — French and English (UI, transcription, AI prompts)
- Full-text search — SQLite FTS5
- Export — Markdown or plain text
- 100% offline — No connection required after model download
| Component | Minimum | Recommended |
|---|---|---|
| macOS | 14.2 (Sonoma) | 15+ (Sequoia) |
| RAM | 16 GB | 32 GB |
| Storage | 10 GB | 20 GB |
| Processor | Apple Silicon (M1) | M2/M3/M4 |
System audio capture requires macOS 14.2+ (ScreenCaptureKit). Intel Macs are not supported.
- Download the DMG from Releases
- Drag VoxTape into Applications
The app is not notarized. macOS will show "app is damaged". Run:
xattr -cr /Applications/VoxTape.app- Open VoxTape
- The setup wizard downloads AI models (~5 GB)
- Grant microphone + screen recording access in System Settings
- Node.js 22+ (recommended: nvm —
nvm install 22) - Rust (required for system audio capture)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y source "$HOME/.cargo/env"
# Clone and install
git clone https://github.com/Lingelo/VoxTape.git
cd VoxTape
npm install
# Build native module (system audio capture)
npm run build:native
# Download AI models (required before first run)
npm run download-model # STT: Silero VAD + Whisper Turbo (~540 MB)
npm run download-llm-model # LLM: Ministral 3B Q4_K_M (~2.1 GB)
# Run in dev mode (hot-reload)
npm run devThe app opens automatically. Angular dev server runs on http://localhost:4200.
Troubleshooting — Electron failed to install correctly or Could not locate the bindings file (better-sqlite3)
Both symptoms mean npm lifecycle scripts were skipped during install, so Electron's binary was never downloaded and better-sqlite3 was never rebuilt against Electron's ABI. The project ships a local .npmrc (ignore-scripts=false) that handles this for most setups. Two cases where it doesn't:
1. You have NPM_CONFIG_IGNORE_SCRIPTS=true in your shell env (common supply-chain hardening). Env vars beat .npmrc per npm config precedence. Reinstall with the CLI flag, which beats env vars:
rm -rf node_modules && npm install --ignore-scripts=false2. You installed deps before pulling the .npmrc. npm sees "up to date" on the next npm install and doesn't replay the scripts. Force the root postinstall once:
npm run postinstallThis re-runs Electron's binary installer (if missing) and rebuilds better-sqlite3 via electron-rebuild.
In dev mode, macOS associates permissions with the Electron binary, not a packaged app. You must manually grant access:
- Open System Settings > Privacy & Security
- For both Microphone and Screen Recording:
- Click +
- Press Cmd+Shift+G to open the path dialog
- Navigate to
<project-root>/node_modules/electron/dist/Electron.app - Add it and ensure the toggle is on
- Quit and relaunch the app — macOS requires a full process restart after granting Screen Recording
Tip: If permissions aren't working, reset and retry:
tccutil reset ScreenCapturethen relaunch the app.
| Command | Description |
|---|---|
npm run dev |
Development mode with hot-reload |
npm test |
Run tests (Vitest) |
npm run build |
Production build |
npm run package |
Create VoxTape.app |
npm run make |
Create DMG + ZIP |
npm run build:native |
Compile Rust native module |
┌─────────────────────────────────────────────────────────────┐
│ Electron Main Process │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ NestJS Backend │ │
│ │ AudioModule → SttModule → stt-worker (sherpa-onnx) │ │
│ │ LlmModule ────────────→ llm-worker (node-llama-cpp) │ │
│ │ DatabaseModule (SQLite) | ConfigModule | ExportModule│ │
│ └───────────────────────────────────────────────────────┘ │
│ IPC Hub (contextBridge) │
└─────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────┴───────────────────────────────────┐
│ Renderer Process (Angular 21 SPA) │
│ SessionService | AudioCaptureService | LlmService │
└─────────────────────────────────────────────────────────────┘
| Project | Stack | Description |
|---|---|---|
apps/electron-shell |
Electron + Vite | Main process + STT/LLM workers |
apps/renderer |
Angular 21 | User interface |
libs/backend |
NestJS 11 | Services (audio, STT, LLM, DB, export) |
libs/shared-types |
TypeScript | Interfaces and IPC constants |
libs/native-audio-capture |
Rust + napi-rs | System audio capture (ScreenCaptureKit) |
| Model | Size | Usage |
|---|---|---|
| Silero VAD | 2 MB | Voice activity detection |
| Whisper Turbo (int8) | 538 MB | Speech-to-text — large-v3-turbo distilled |
| Ministral 3B Q4_K_M | 2.1 GB | Summaries and chat |
- Fork the project
- Create a branch (
git checkout -b feature/my-feature) - Commit (
git commit -m 'feat: add my feature') - Push (
git push origin feature/my-feature) - Open a Pull Request
MIT — See LICENSE