# 002 — v1.1 Multi-Library Support > Lets users register and manage multiple music library directories with per-library scanning, filtered views, cross-library playlists, and phantom-track preservation when a library is removed. **Shipped:** 2026-03-16 · **Phases:** 9-14 ## What landed - **Phase 9 — Scan cancellation & keyboard shortcuts.** Cancellable/pausable library scans via per-scan context; configurable shortcuts with record-style capture, scope-aware dispatch, conflict detection. - **Phase 10 — Schema & migration.** New `libraries` table, `library_id` FK on `audio_files`, phantom columns on `playlist_tracks`, seamless single-directory → named-library migration on first launch. - **Phase 11 — Per-library scan pipeline.** Sequential scan-queue coordinator (single writer is the SQLite reality); per-library progress UI with library name; cancel scope respects the active library. - **Phase 12 — Library CRUD & data integrity.** Add/rename/remove library through UI; atomic orphan cleanup (shared artists/albums/genres survive); FTS5 entries removed; queue tracks from a removed library cascade-deleted with playback continuing. - **Phase 13 — Library views & phantom tracks.** Library filter dropdown across all views; tracks/albums/artists/genres/search respect the active filter; cross-library playlists work naturally; removed-library tracks become greyed-out phantoms with preserved metadata, auto-resolved on rescan via `ScanHooks` + M3U8 matching. - **Phase 14 — Performance optimization.** CSS containment + GPU promotion on scroll containers; view caching (display toggle, no DOM destruction); event delegation on virtualizer; `queueMicrotask` notification batching; pprof profiling guide. ## Key decisions retained - **Hybrid model — `library_id` only on `audio_files`.** Physical files belong to a library; logical entities (artist/album/genre) are shared. - **Libraries live in DB, not TOML.** UI-driven CRUD shouldn't require TOML manipulation. - **`SET NULL` on `playlist_tracks` FK.** Phantom rows preserve playlist structure when a library is removed. - **Backend filters, frontend doesn't.** `ByLibrary` SQL variants keep the UI responsive at 150k tracks. - **Sequential scanning.** SQLite single-writer makes parallel scans pointless. - **`ScanHooks` callback pattern.** Breaks the library → playlist circular dep needed for phantom resolution.