# koring-launcher Minecraft launcher built with Electron + React 19 + TypeScript + Node.js (@xmcl). ## Quick commands ```bash pnpm dev # full app dev (renderer + main process) pnpm dev:renderer # frontend only (vite, port 1420) pnpm dev:main # electron main process only pnpm build # production build (vite + tsc) pnpm dist:dev # dev icon + Windows installer pnpm dist:beta # beta icon + Windows installer pnpm dist:run # production icon + Windows installer ``` ## Architecture - **Frontend** (`src/`): React 19 + Vite 7 + Tailwind v4 + shadcn/ui + Zustand stores - **Main Process** (`electron/`): Node.js/TypeScript, manages windows, IPC handlers, @xmcl/* packages - **Icon System** (`public/icons/{dev,beta,run}/`): Mode-specific icons, copied to `build/` at build time - IPC: Frontend → `ipcRenderer.invoke()` → `ipcMain.handle()` → main process → `webContents.send()` → Frontend ## Key gotchas - **Electron main process**: `electron/main.ts` is the entry point. All @xmcl/* packages run here. - **Preload script**: `electron/preload.ts` exposes `window.electronAPI` via context bridge. - **IPC handlers**: All handlers are in `electron/handlers/` directory. - **Mutable win ref**: `electron/main.ts` uses a mutable `win` object — handlers read `win.mainWindow` at runtime, not at registration time. - **Config**: YAML format (`Koring.yml`) stored next to executable. Sparse save (only non-default values). - **Auth**: JSON file (`koring-auth.json`) stored next to executable. - **Path alias**: `@/` maps to `src/` (configured in `vite.config.ts` and `tsconfig.json`). - **Dev mode**: Vite runs on port 1420, Electron loads from localhost. - **Asset paths**: Use `import.meta.env.BASE_URL` prefix for public assets. Absolute paths break in packaged app. ## Build & bundle ```bash pnpm build # Vite build + TypeScript compile pnpm dist:dev # switch-icon dev + electron-builder Windows installer pnpm dist:beta # switch-icon beta + electron-builder Windows installer pnpm dist:run # switch-icon run + electron-builder Windows installer ``` Each `dist:*` command runs: `pnpm build` → `pnpm icon:{mode}` → `electron-builder --win` ## Icon switching ``` public/icons/ dev/icon.ico, icon.png beta/icon.ico, icon.png run/icon.ico, icon.png build/ ← generated by switch-icon.js (gitignored) icon.ico icon.png ``` `electron-builder.yml` uses `buildResources: build` to read icons from `build/`. ## Electron notes - `electron/main.ts`: App entry, window management, splash→main transition (ready-to-show + 1.5s min) - `electron/preload.ts`: Context bridge for secure IPC - `electron/config.ts`: YAML config management (sparse save) - `electron/auth.ts`: Auth data persistence (JSON file) - `electron/core/`: @xmcl/* integrations (auth, installer, launcher, modrinth, instance) - `electron/handlers/`: IPC handlers (config, auth, install, launch, mods, instance, background, task, system, window) ## Frontend notes - `src/api/ipc.ts`: Core IPC utilities (invoke, onIpcEvent) - `src/api/*.ts`: API modules wrapping IPC calls - `src/stores/`: Zustand state management - `src/hooks/useTheme.ts`: Dark mode sync with Electron theme - `src/components/system/WindowControls.tsx`: Custom window controls (min/max/close), uses `