Desktop-first AI note taker with a local-first Electron UX, a Next.js web app, and FastAPI/LangChain backends.
Licensed under the MIT License. Third-party programs are listed in NOTICE.
You can open the desktop app and keep notes on this machine without an account. Sign in only when you want Google Drive mirror or the web account vault.
Notebook AI is a monorepo:
apps/desktop: Electron + React + Vite desktop recorder/editorapps/web: Next.js landing, signup/signin, onboarding, and web settingsservices/local-sidecar: local FastAPI note/transcript APIservices/cloud-api: hosted FastAPI auth/provider/settings APIpackages/contracts: shared TypeScript API contractspackages/theme: shared design tokens (light/dark)packages/ui: shared React primitives
flowchart TB
subgraph machine["Your machine"]
Desktop["Desktop app<br/>Electron · React · Vite"]
Web["Web app<br/>Next.js"]
Sidecar["Local sidecar<br/>FastAPI · LangChain"]
Notes[("Markdown notes<br/>on disk")]
Desktop -->|"localhost"| Sidecar
Sidecar --> Notes
Desktop -->|"open sign-in in browser"| Web
end
subgraph network["Network"]
Cloud["Cloud API<br/>FastAPI"]
Supabase["Supabase"]
Providers["Provider APIs<br/>OpenAI · OpenRouter · …"]
Cloud --> Supabase
end
Web -->|"signin · onboarding · BYOK"| Cloud
Desktop -->|"desktop auth exchange · Drive OAuth flows"| Cloud
Sidecar -->|"streamed transform · transcription"| Providers
A sidecar here is a small local HTTP service you run next to the desktop app (not a second cloud). It exists so normal work stays local-first and low-latency:
- Notes: Create, list, and save markdown through the sidecar so content stays on your filesystem and the UI does not depend on a remote service for every edit.
- AI and transcription: Streaming transforms and audio round-trips go to the sidecar on
localhost, which talks to provider APIs using keys from the sidecar.envor keys saved locally by the desktop app on that device.
The cloud API is a separate companion: Supabase auth validation, session refresh/logout, web/mobile provider vault storage, storage preferences, desktop auth handoff, and Drive integration metadata. It does not store your note markdown or sit in the path for debounced note persistence. Desktop notes, local provider keys, transcription, and AI work without signing in. Google Drive mirror and the web vault require an account.
Credential scope is intentionally split:
-
Desktop BYOK is stored locally on the device through
services/local-sidecarand is not synced to the account vault. -
Web and future mobile clients store BYOK only in the cloud API's encrypted account vault.
-
Hosted AI routes can use vault credentials server-side, but raw provider secrets do not go back to browser or mobile clients.
-
Fast local-first note editing with debounced persistence
-
Streaming AI action panel (
summarize,rewrite,extract_action_items) -
Unified web + desktop visual system with shared tokens/components
-
Dark and light themes with persisted preference
Follow Getting started to install dependencies, run the desktop app without an account, and optionally start the cloud API.
The public Mac download will live on the domain you attach. Set NEXT_PUBLIC_DESKTOP_DOWNLOAD_URL to that URL when the domain is ready. Until then, Download for Mac opens the GitHub latest release.
Copy the placeholder file and leave secrets empty:
services/local-sidecar/.env.exampleservices/cloud-api/.env.exampleapps/desktop/.env.exampleapps/web/.env.example
Do not commit .env files. Audio transcoding uses ffmpeg on your PATH when it is installed. Releases do not bundle ffmpeg.
-
VERSIONis the repo-wide source of truth. -
Run
npm run version:syncafter bumpingVERSION. -
Generate release notes with
npm run release:notes -- --version <x.y.z>. -
Build the macOS sidecar package with
npm run release:sidecar:mac. -
Build the macOS desktop DMG with
npm run release:desktop:mac. -
See docs/releases/PROCESS.md for branch naming and release cadence.
-
Local sidecar:
POST /notesGET /notesPUT /notes/{id}PATCH /notes/{id}/moveDELETE /notes/{id}GET /foldersPOST /foldersPATCH /folders/{id}DELETE /folders/{id}GET /storage/local-rootPUT /storage/local-rootGET /storage/preferencePUT /storage/preferenceGET /sync/statusPOST /sync/runPOST /ai/transform/stream(SSE)GET /providers/statusPOST /providers/byokGET /providers/modelsDELETE /providers/{provider}
-
Cloud API:
POST /auth/session/refreshPOST /auth/logoutGET /settings/storagePUT /settings/storagePOST /providers/openai/oauth/startGET /providers/openai/oauth/callbackPOST /integrations/google-drive/oauth/startGET /integrations/google-drive/oauth/callbackGET /integrations/google-drive/statusPOST /integrations/google-drive/access-tokenPOST /providers/byok(web/mobile encrypted account vault)GET /providers/statusGET /providers/credential(server-side use only)DELETE /providers/{provider}