Coding
PromptBeginner5 minmarkdown
Markdown Converter
Agent skill for markdown-converter
7
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Sign in to like and favorite skills
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
YouTube Local is an Electron + React desktop application for managing and playing a personal video library stored on local or external drives. Videos are indexed in-place (never copied) with metadata persisted in SQLite.
npm run dev # Start Vite + Electron concurrently (main workflow) npm run dev:vite # Vite dev server only (port 5173) npm run dev:electron # Electron only (requires Vite running) npm run build # Build React/Vite production bundle npm run build:electron # Create distributable packages via electron-builder npm run rebuild # Rebuild native modules (better-sqlite3)
After
npm install, the postinstall script automatically runs electron-rebuild for better-sqlite3.
src/main/): Node.js runtime - handles database, file system, FFmpeg operationssrc/renderer/): React app - UI and user interactionssrc/preload/index.js): Secure IPC bridge exposing window.electronAPI| File | Purpose |
|---|---|
| Window creation, app lifecycle |
| SQLite schema, better-sqlite3 connection, prepared statements |
| Recursive video file discovery |
| Chokidar-based real-time monitoring |
| Multi-disk detection and reconnection handling |
| FFmpeg thumbnail extraction |
| IPC handlers grouped by feature |
All renderer-to-main communication uses
ipcRenderer.invoke() through the preload bridge:
// Renderer calls const videos = await window.electronAPI.getVideos(filters); // Main process handles via ipcMain.handle() ipcMain.handle('get-videos', async (event, filters) => { ... });
Event listeners return unsubscribe functions:
const unsubscribe = window.electronAPI.onSyncProgress(callback); // Later: unsubscribe();
database/youtube-local.dbvideos, watch_folders, categories, tags, playlistsvideo_categories, video_tags, playlist_videosfile_hash (MD5 of filepath + fileSize) for identity tracking across disk locationssrc/renderer/src/ ├── App.jsx # Router and main layout ├── components/ # Reusable UI components ├── pages/ # Route-based views (Home, Video, Settings, etc.) ├── context/ # React Context (SearchContext) ├── hooks/ # Custom hooks (usePagination) └── utils/ # Helpers (videoSortFilter)
is_available = 0 when file missingdisk_identifier + relative_filepath enable reconnection detectiondb.prepare(sql).run(...args)db.transaction(() => { ... })()When state changes in main process, broadcast to renderer:
mainWindow.webContents.send('sync-complete', data);
contextIsolation: true, nodeIntegration: falsewebSecurity: false required for local file:// video playbacksandbox: false required for better-sqlite3 native moduleusePagination hookthumbnails/ directory (gitignored)@ffmpeg-installer/ffmpeg