3fb4a9685fedabe45b9247df4eb00723e8b27545
Phase 4 of the 0.1.0 release prep: - tauri-plugin-log: rotating file log (5 MB, Info) in the app log dir plus stdout; all 54 backend println!/eprintln! sites migrated to log macros so release builds finally produce diagnostics - tauri-plugin-single-instance (registered first): second launches focus the existing window instead of racing the same SQLite DB with a second worker fleet; tauri-plugin-window-state persists window geometry - real CSP replacing null (scripts self-only, media/images via the asset protocol, IPC endpoints whitelisted, object-src none) with a devCsp variant for Vite HMR - asset protocol scope narrowed from '**' to thumbnails statically plus per-folder runtime grants (setup, add_folder, update_folder_path) Panic audit (plan item) concluded with no changes: worker loops already catch and log all Result errors; remaining unwraps are startup fail-fast, poisoned-lock convention, infallible-by-construction, or test code.
Phokus
A local-first desktop media library for browsing, filtering, and curating image and video folders.
Features
Library
- Add and remove media folders; background indexing with live progress
- Live file tracking — a filesystem watcher keeps the library in sync as files are added, changed, or removed; renames and moves are handled in place, preserving thumbnails and embeddings
- Browse all media or filter by folder, type (image/video), favorites, or star rating
- Sort by date added, date taken (EXIF), name, size, rating, or duration
- Grid density controls (compact / comfortable / detail)
- Desktop notifications, batched per folder, with per-folder mute and a global pause
Search & discovery
- Filename search, semantic search (
/s query), and tag search (/t tag) - Similar image search — find visually similar media by image or a selected region
- Explore view — visual cluster map and tag cloud for browsing by theme
- Timeline view — media grouped chronologically by capture date (EXIF)
- Duplicate finder — three-phase exact-duplicate scan (size → sample hash → full hash) with live progress and bulk delete
- Explore, Timeline, and Duplicates are folder-scopable directly from their headers — no need to bounce through the sidebar
Viewing & curation
- Lightbox with keyboard navigation, zoom, inline tag editing, and rating controls
- Custom video player — immersive edge-to-edge playback with scrubbing, volume, playback speed, loop, and fullscreen; auto-hiding controls and full keyboard support
- AI tagging via WD tagger (ONNX, CPU/DirectML) with confidence threshold, batch size, and per-folder queue targeting
Maintenance
- Database compaction and orphaned-thumbnail cleanup from Settings, with live size/reclaimable stats
- Per-folder pausing of background work (thumbnails, metadata, embeddings, tagging)
Supported formats
| Images | Videos |
|---|---|
| jpg, jpeg, png, gif, bmp | mp4, mov, m4v |
| tiff, tif, webp, avif, heic, heif | webm |
Stack
- Tauri 2 + Rust backend
- React 19 + TypeScript + Zustand
- SQLite +
sqlite-vec(vector search) + HNSW index - ONNX Runtime (
ort) for AI tagging - Candle (Rust ML) for CLIP visual embeddings
- mozjpeg for fast scaled JPEG decoding
- FFmpeg sidecar for video thumbnails and metadata
- Vite + Tailwind CSS v4
Development
Prerequisites: Node.js 20+, pnpm, Rust toolchain, Tauri system prerequisites for Windows.
pnpm install
# Run with hot-reload (frontend + Rust)
pnpm dev:app
# Frontend only
pnpm dev:vite
# Production build
pnpm build:app
# Type-check the frontend
pnpm build:vite
How it works
- Add a folder from the sidebar — the Rust indexer walks it recursively.
- Supported files are written to SQLite with metadata (path, dimensions, media type, EXIF capture date, etc.).
- Background workers process the queue as a strict priority pipeline — thumbnails first, then video metadata, then visual embeddings, then AI tags — so each stage runs at full speed instead of competing for CPU, disk, and the database.
- Progress events stream back to the UI while the gallery updates incrementally.
- A filesystem watcher picks up later changes (new files, edits, deletions, renames) and keeps the index current without rescans.
- Embeddings power semantic search and the similar-images feature via an HNSW index.
Languages
TypeScript
60.4%
Rust
37.5%
CSS
1.3%
Shell
0.4%
JavaScript
0.2%
Other
0.2%