Self-hosted, team-friendly AI meeting notes. Record, transcribe, diarize, and turn conversations into structured notes — all on your own infrastructure.
EchoNoting captures audio from your mic and system output, transcribes it in real time with Whisper, separates speakers with Pyannote, and uses Claude to extract decisions, action items, open questions, and context as the meeting unfolds. No SaaS lock-in, no third-party recording bot sitting in your calls — just a desktop app and an API you control.
Most meeting-notes tools either ship your audio to someone else's cloud or require a bot to join every call. EchoNoting takes a different approach:
- Runs on your hardware. Postgres, Redis, Whisper, Pyannote — all in Docker on your box. Only the Claude API call leaves your network.
- Captures system audio + mic separately. Works for any meeting platform, podcast, or interview. No browser extension, no platform integration needed.
- Real-time, not after-the-fact. Transcripts and structured notes stream in live while the meeting is happening.
- Speaker diarization with persistent voice profiles. Recognizes the same speakers across sessions and lets you rename them inline.
- Team-friendly. Workspaces, invites, shared sessions, notifications, comments on notes.
- Export anywhere. Markdown and JSON export, public share links, copyable transcripts.
- Live transcription via Whisper with word-level timestamps
- Live AI note extraction (Decisions / Action items / Open questions / Context) via Claude
- Post-session summary generation
- Speaker diarization + persistent voice profiles (cosine-matched across sessions)
- Inline speaker rename, talk-time stats
- Persistent recording with pause/resume and mic mute
- Floating recording bar, system tray integration (desktop)
- Workspaces, invites, role-based access
- Notifications, note comments, shared session links
- Full-text search and
⌘Kcommand palette - Markdown + JSON export
- Native desktop app (Tauri) on macOS / Windows / Linux + a web companion
| Layer | Tech |
|---|---|
| Desktop | Tauri 2, React 19, Vite, TanStack Router |
| Web | React 19, Vite, React Router v7, TanStack Query v5 |
| UI | Tailwind CSS v4, shadcn/ui (New York), Geist |
| Backend | ElysiaJS on Bun, Eden Treaty (end-to-end types) |
| Auth | Better Auth |
| DB | PostgreSQL 16 + pgvector, Drizzle ORM |
| Queue | BullMQ + Redis |
| Transcription | Whisper REST (onerahmet/openai-whisper-asr-webservice) |
| Diarization | Pyannote, FastAPI sidecar |
| LLM | Anthropic Claude (claude-sonnet-4-5) |
| Monorepo | Turborepo + Bun workspaces |
┌──────────────┐ mic + system audio ┌─────────────┐
│ Desktop / │ ─────── WebSocket ───► │ ElysiaJS │
│ Web client │ ◄── live transcript ── │ API │
└──────────────┘ ◄── live AI notes ── └──────┬──────┘
│
┌───────────────────────┼──────────────────────┐
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Whisper │ │ Pyannote │ │ Claude │
│ (transcribe)│ │ (diarize + │ │ (extract + │
│ │ │ embed) │ │ summarize) │
└─────────────┘ └─────────────┘ └─────────────┘
- The client captures mic and system audio as separate streams.
- Chunks stream to the API over WebSocket.
- The API fans out to Whisper and Pyannote, persists segments, and matches voices to known profiles.
- Every few segments, a BullMQ worker calls Claude to extract structured notes (filtered by confidence).
- Results stream back to every connected client in real time.
- On session end, a full summary is generated.
- Bun ≥ 1.3
- Docker + Docker Compose
- An Anthropic API key
- A HuggingFace token (for Pyannote model download)
- For the desktop app: Rust toolchain (rustup)
git clone https://github.com/AimeurAmin/echonoting.git
cd echonoting
bun installcp .env.example .env
# Fill in ANTHROPIC_API_KEY, HUGGINGFACE_TOKEN, BETTER_AUTH_SECRET, ...docker compose up -d # postgres, redis, whisper, pyannotebun --cwd apps/api run db:push
bun dev # starts api + web via Turbo
# or, for the desktop app:
bun run desktopWeb: http://localhost:5173 · API: http://localhost:3001
apps/
desktop/ Tauri 2 desktop app (primary client)
web/ React + Vite web companion
api/ ElysiaJS backend on Bun
packages/
types/ Shared Zod schemas + TS types
utils/ Shared utilities
services/
pyannote/ FastAPI diarization sidecar
docker-compose.yml Local dev services
docker-compose.prod.yml
Each app and package keeps its own MAP.md documenting endpoints, components, DB tables, and env vars.
bun dev # run everything
bun run desktop # desktop only
bun run api # api only
bun --cwd apps/api run db:push # sync schema (dev)
bun --cwd apps/api run db:generate # generate migration
bun --cwd apps/api run db:migrate # apply migrations
bun --cwd apps/api run db:studio # Drizzle Studio
docker compose up -d # start local services
docker compose logs -f whisper # tail a serviceA docker-compose.prod.yml ships everything you need to self-host. Release builds for the desktop app are produced via Tauri (see apps/desktop/src-tauri) and the GitHub Actions workflow in .github/workflows/release.yml.
All six implementation phases (scaffold → auth → live transcription → AI notes → diarization → team features → polish & export) are complete. The desktop app is the primary client; the web app stays feature-equivalent. See PROGRESS.md for the full history.
Issues and PRs are welcome. If you're filing a bug, please include:
- OS + version
- Desktop app version (or "web")
- Steps to reproduce, expected vs. actual behavior
For larger changes, open an issue first to discuss the approach.
MIT © Amin Aimeur