Desktop app · case study
Notecom Desktop
Desktop build of Notecom that generates lessons with the user's own Claude Code CLI, with no API key stored.

- My role
Sole developer
- Type
Desktop application
- Stack
Tauri, Rust, Next.js, TypeScript
Why I built it
The desktop build of Notecom exists for the one thing the website can't do: generate notes.It runs the user's own Claude Code CLI on their own subscription, so no API key is stored anywhere.I built it as part of Notecom.
The problem
Generating notes needs a signed-in Claude Code CLI, which a hosted website doesn't have.
Installing it should take one download, not a clone and a terminal.
Features
- Generates lessons and quizzes from uploaded slides/PDFs
- Runs generation in the background, up to 3 at once
- Auto-refreshes the tree when a file lands
- Only this build (or your dev machine) can generate - hosted web can’t
Architecture
- Tauri shell to Node sidecar: spawns
- Tauri shell to Native webview: opens
- Native webview to Node sidecar: HTTP
- Node sidecar to claude CLI: spawns job
- Node sidecar to vault/: import (read)
- claude CLI to vault/: writes
- Node sidecar to Supabase Auth: sign-in
- Node sidecar to Postgres + RLS: anon key + JWT
In words
A Rust Tauri shell picks a free port and starts a bundled Node sidecar.The sidecar runs the Next.js standalone server on 127.0.0.1, and a native window opens on it.Generation spawns the user's own Claude Code CLI, which writes lessons to a local vault folder.The app imports those files into the same Supabase project as the web app, under the same RLS.
Pipeline
push → main
GitHub Actions
type-check only, fast on purpose
tag v*.*.*
OS matrix
Windows and Linux; macOS job failing
Bundle
Next standalone + Node sidecar
tauri build
Rust shell, per-OS installers
GitHub Release
.msi .exe .AppImage .deb
Decisions
- Use the user's own Claude Code CLI, not an API key.
No per-token charges on top of the user's subscription.No shared key serving several people.
- A per-user project folder, resolved at launch.
An installer built on one machine works on any other.
Challenges
- Stopping every process on exit.
On Windows, taskkill ends the whole process tree.A plain kill leaves children running.
- Two generations writing to the same folder at once.
Jobs queue per folder, with up to three running at once.Lesson numbers never collide.
Testing
Every version tag builds installers for Windows, Linux and macOS.
Not yet: the macOS job fails at the Rust build.v0.1.0 shipped for Windows and Linux only.
Outcome
v0.1.0 released for Windows (.exe, .msi) and Linux (.AppImage, .deb).
Next
Fix the macOS universal build
Stack
- Tauri
Packages the app as a native window and manages startup.
- Rust
Runs the native shell beneath Tauri.
- Next.js
Runs the UI and the background job queue.
- TypeScript
Types the note generation pipeline.
Security
- Authentication
The web app's Supabase session.The shell holds no credentials of its own.
- Input validation
Generation runs only on files the user attaches.Its rules live in the command files, not the app.
- Protections
No API key stored anywhere.Generation uses the user's own signed-in Claude CLI.