BrowserWindow and handles platform-level concerns: system tray, OAuth deep links, auto-updates, and native title bar styling.
Scaffold with the CLI
When you runnpx @chat-js/cli@latest create, the CLI asks:
electron/ subfolder inside your project:
owner and repo in electron-builder.config.js. The app name, URL scheme, appId, and production URL all derive automatically from chat.config.ts.
Development
Start the Next.js web app first, then launch Electron pointing atlocalhost:3000:
src/config.ts sets APP_URL to http://localhost:3000 automatically when NODE_ENV === "development".
DevTools open in a detached window automatically in development mode.
Authentication
OAuth cannot redirect back to a traditionalhttp:// URL inside Electron. The integration solves this with a custom URL scheme deep link.
How it works
The exchange token is a short-lived HMAC-signed value (60 second expiry) derived from yourAUTH_SECRET. No database or shared state is required.
Your web app already includes the two API routes that support this:
GET /api/auth/electron-callback— reads the session cookie after OAuth completes, signs it into a short-lived token, and redirects to the deep link URLGET /api/auth/electron-exchange?token=...— verifies the signed token and returns the raw session token so Electron can set the cookie
Configuring the URL scheme
The URL scheme (e.g.myapp, which produces deep links like myapp://auth/callback) comes from the appPrefix field in chat.config.ts. Update it there and the change propagates automatically to src/config.ts and electron-builder.config.js via the prebuild step.
System Tray
The app minimizes to the system tray instead of quitting when you close the window. The tray icon shows a context menu with Show and Quit options. Closing the window hides it. Use Quit from the tray to fully exit.Auto-Updates
The integration useselectron-updater with GitHub Releases as the update source. When a packaged app starts, it checks for updates automatically and installs them on next quit.
The publish block in electron-builder.config.js controls the GitHub repository:
owner and repo from your project. Updates only run when the app is packaged (app.isPackaged). They are skipped in development.
Customization
App icon
Replaceelectron/icon.png with your own 512x512 PNG, then regenerate platform icons:
build/icon.png and build/icon.icns (macOS).
App name, scheme, and production URL
All branding values come fromchat.config.ts in your project root. Edit the relevant fields there:
bun scripts/write-branding.ts, which reads chat.config.ts and writes a branding.json file. electron-builder.config.js reads branding.json at build time to set productName, appId, protocol schemes, and copyright.
You do not need to edit any files inside electron/ to change the app name, scheme, or URL.
Building for Distribution
Build a distributable installer with one of the platform commands:electron/release/. To install:
- macOS — run
open release/ChatJS-0.1.0-arm64.dmg, then drag the app to your Applications folder - Windows — run the
.exeinstaller - Linux — make the
.AppImageexecutable and run it
bun run package. This produces an unpacked app directory in release/ that you can launch directly without going through an install step.
For macOS distribution outside the App Store, the build uses hardened runtime with the entitlements in entitlements.mac.plist. Notarization requires additional setup with your Apple Developer account.