This file provides guidance to Claude Code when working with this repository.
Desktop Starter App is an Electron desktop application template with production-quality infrastructure including auto-updates, SQLite database, settings management, and CI/CD pipelines.
- Electron - Desktop framework
- React 19 - UI framework
- TypeScript - Type safety
- Vite - Build tool
- Tailwind CSS - Styling
- better-sqlite3 - SQLite database
- electron-updater - Auto-updates
- electron-forge - Build/packaging
npm run dev # Start development server with hot reload
npm run start # Clean build and start dev server
npm run make # Build distributable packages for current platform
npm run publish # Build and publish to GitHub Releases
npm run lint # Run ESLint
npm run format # Format with Prettier
npm run test # Run tests-
Main Process (
src/main.ts)- Node.js environment
- Creates browser windows
- Handles system APIs (file dialogs, menus)
- Manages auto-updates
- Initializes database
-
Preload Script (
src/preload.ts)- Bridge between main and renderer
- Exposes
window.apiobject - Uses contextBridge for security
-
Renderer Process (
src/renderer/)- React application
- Isolated browser context
- Communicates via
window.api
src/database/- SQLite connection, config, and schemasrc/ipc/handlers.ts- IPC handlers for main processsrc/types/window.ts- Type definitions forwindow.apisrc/renderer/- React components and styles
Uses SQLite with better-sqlite3. WAL mode enabled for concurrent access.
Tables:
settings- Key-value store for app configuration
Schema defined in src/database/schema.ts.
IMPORTANT: When making changes to existing tables, make sure to create migrations in separate files.
All IPC handlers return IPCResponse<T>:
interface IPCResponse<T> {
success: boolean;
data?: T;
error?: { code: string; message: string };
}-
Add handler in
src/ipc/handlers.ts:ipcMain.handle('myFeature:action', async (_, arg) => { try { return { success: true, data: result }; } catch (error) { return { success: false, error: { code: 'ERROR', message: String(error) } }; } });
-
Add method in
src/preload.ts:const myFeatureAPI = { action: (arg: string) => ipcRenderer.invoke('myFeature:action', arg), };
-
Add types in
src/types/window.ts -
Add to
contextBridge.exposeInMainWorld()
The single source of truth for app configuration. This file is committed to the repo.
export const config = {
productName: 'Desktop Starter App',
executableName: 'desktop-starter-app',
appBundleId: 'com.example.desktop-starter-app',
appDataFolder: 'DesktopStarterApp',
dbFilename: 'app.db',
github: {
owner: 'dotnetfactory',
repo: 'desktop-starter-app',
private: false,
},
autoUpdateEnabled: true,
maintainer: 'Your Name <your@email.com>',
};The config is injected at build time via Vite's define and available as __APP_CONFIG__ globally.
.env is for secrets only (gitignored):
GH_TOKEN- GitHub PAT for private repo accessAPPLE_*- macOS signing credentials
forge.config.ts- Importsapp.config.tsfor build settingsvite.main.config.ts- Injects__APP_CONFIG__into main processvite.renderer.config.ts- Injects__APP_CONFIG__into renderervite.preload.config.ts- Preload script build config
app.config.ts- App configuration (single source of truth)src/main.ts- Main process entry, window creation, auto-updatersrc/preload.ts- API bridge exposed to renderersrc/ipc/handlers.ts- All IPC handlerssrc/database/schema.ts- Database table definitionssrc/renderer/App.tsx- Main React componentforge.config.ts- Build and packaging configuration