Vellum
Desktop AI/RP chat app built with Electron, a local Express API, and SQLite.
- Use
npm run devfor daily development. - Use
npm run dist:mac/npm run dist:winfor desktop bundles. - CI desktop builds are currently unsigned, so target OSes may require manual confirmation.
- Desktop packaging works, but still has rough edges. Expect occasional startup/build quirks.
- Electron
- React + TypeScript + Vite
- Express
- better-sqlite3
- Tailwind CSS
- Chat with branching, edit/delete, regenerate, and multi-character auto turns.
- RP tools: prompt blocks, author note, scene state, presets.
- User personas included in generation context.
- Character cards: import, validate, edit.
- Creative Writing mode: projects, chapters, scenes, consistency check, export.
- Desktop packaging for macOS and Windows via electron-builder.
- Node.js + npm (LTS recommended; project uses native module
better-sqlite3). - Python 3 + Pillow for icon generation (
pip install pillow).
- Install dependencies:
npm install- Start frontend + backend:
npm run dev- Open:
http://localhost:1420
- macOS:
./setup-and-run-dev.sh- Windows (CMD/PowerShell):
setup-and-run-dev.batWhat these scripts do:
- try to install Node.js LTS automatically (macOS:
nvm/brew, Windows:winget); - run
npm install; - start
npm run dev.
npm run dev:electron- All platforms:
npm run dist- macOS only:
npm run dist:mac- Windows only:
npm run dist:winBuild output is written to release/.
Workflow:
.github/workflows/build-desktop.yml
What it does:
- Builds macOS (
x64+arm64) and Windows (x64) desktop bundles. - Uploads build outputs as Actions artifacts.
- On tag push
v*, publishes binaries into GitHub Releases automatically.
Generate icons:
npm run build:iconsThe script creates:
build/icon.pngbuild/icon.icnsbuild/icon.ico
These files are used by electron-builder in package.json.
npm run dev- frontend + server.npm run dev:server- backend only (tsx watch server/index.ts).npm run dev:frontend- Vite frontend only.npm run dev:electron- Electron + frontend + server.npm run rebuild:native- manualbetter-sqlite3rebuild.npm run test- run tests (vitest run).
- In dev: local
data/. - In packaged app:
SLV_DATA_DIRis mapped toapp.getPath("userData")/data.
Cause: native module was built for a different Node ABI.
Fix:
- Run:
npm run rebuild:native- If needed, remove
node_modulesandpackage-lock.json, then runnpm install. - Ensure dev/build use the same Node version.
Note: scripts/ensure-better-sqlite3.cjs runs automatically before dev:server.
Cause: port 3001 is occupied by an old server process.
Fix:
- Restart
npm run dev(ensure-dev-port.cjstries to free the port). - If still occupied:
lsof -nP -iTCP:3001 -sTCP:LISTEN
kill -TERM <pid>Check:
- You ran full desktop build (
npm run dist), not just frontend build. - Package includes
dist/,dist-electron/, andserver-bundle.mjs. - In production, Electron waits for
GET /api/healthfrom bundled server.
src/- React frontend.server/- Express API.electron/- Electron main/preload.scripts/- utility scripts (native rebuild, ports, icons).build/- electron-builder resources.release/- built.app,.dmg,.exe, installers.