apps/lite/README.md
Electron + React (Vite) + TanStack Router scaffold.
ui/: renderer/frontend codeelectron/: main process and preload codeui imports IPC API types directly from electron/src/ipc.ts using type-only imports for end-to-end type safety.
ui/ and privileged Electron code in electron/.tsc (no extra bundler for main/preload)electron/ TypeScript with tsc only (build:electron).electron-builder via the package script.ui/tsconfig.json, electron/tsconfig.json) plus root project references.moduleResolution: bundler in UI, NodeNext in Electron). Separation prevents subtle config conflicts.electron/src/ipc.ts; preload implements and exposes window.lite; UI consumes types through ambient declaration.contextIsolation: true, nodeIntegration: false, and only expose approved API via contextBridge.#electron/*) and type-only imports.pnpm --filter @gitbutler/lite dev: run Vite + Electronpnpm --filter @gitbutler/lite build: build renderer and Electron codepnpm --filter @gitbutler/lite check: TypeScript checks for both targetspnpm --filter @gitbutler/lite package: build and package with Electron BuilderNo app-local ESLint config is added. The monorepo root flat config in eslint.config.js ignores apps/lite/**, and Lite is linted via oxlint instead.
electron/src/ipc.tswindow.liteui/src/electron.d.ts@gitbutler/but-sdk integrationapps/lite consumes Rust bindings via @gitbutler/but-sdk using a strict process boundary:
electron/src/main.ts that call native bindings (for example listProjectsStatelessNapi).electron/src/ipc.ts and carries SDK-generated types such as ProjectForFrontend.contextBridge in electron/src/preload.cts.window.lite.* and never imports or calls native bindings directly.This keeps native module access in privileged code while preserving end-to-end TypeScript safety in the renderer.