The Problem
Managing an Apple Photos library and synchronizing it with an Immich server requires manual export, checksum tracking, and folder organization. Users need a tool that handles incremental updates, Live Photo pairing, and metadata sync without data loss, but existing solutions often lack native macOS integration or reliable incremental logic.
What This Does
ImmiBridge is a macOS desktop application built in Swift that copies and syncs an Apple Photos library to Immich or a local folder. The core logic resides in ImmiBridge/ImmiBridge/Core/, where PhotoBackupCore.swift and FileImmichSync.swift manage the backup modes (Smart Incremental, Full, Mirror) and handle the export of originals and Live Photo paired videos. The user interface is defined in ImmiBridge/ImmiBridge/UI/, with PhotoBackupViewModel.swift and ContentView.swift serving as the primary state management and presentation layers. Configuration for the Immich connection (server URL and API key) is handled within the UI tab, utilizing SHA1 checksums to prevent duplicate uploads.
How It Is Wired
Execution starts at ImmiBridge/ImmiBridgeUI/PhotoBackupApp.swift, the SwiftUI entry point. User inputs flow into PhotoBackupViewModel.swift, which orchestrates the backup process. The model delegates to PhotoBackupCore.swift for local filesystem operations and FileImmichSync.swift for network interactions with the Immich API. AssetMappingStore.swift and ManifestStore.swift maintain the state required for incremental syncs. A significant blast radius exists in the three oversized files—PhotoBackupCore.swift, PhotoBackupViewModel.swift, and ContentView.swift—which together contain substantial line counts, meaning changes in one ripple widely across the UI and core logic. Duplicated 6-line blocks are evident across six core files, indicating a need for refactoring shared helpers. The import graph is flat, with 27 files analyzed and no circular dependencies detected.
How To Use It
Setup:
git clone https://github.com/moses-y/immibridge.git
cd immibridge
open ImmiBridge/ImmiBridge.xcodeproj
Configuration requires an Immich server URL and API key, which are set within the app's Destination tab. The .env.example file in the root provides pattern guidance for environment variables if building outside Xcode.
Running it: Launch ImmiBridge from the Applications folder. Grant Photos access on first run. Navigate to the Destination tab, enter the Immich server URL and API key, and click Test Connection. Select a backup mode and initiate the sync.
Real-World Use
A user wishing to migrate their photo collection to Immich connects their macOS machine to their local network, launches ImmiBridge, points the source to their Photos library, and enters their Immich server details. The app performs an incremental sync, using SHA1 checksums to identify and upload only new or modified files, including the paired video component of Live Photos, organizing the destination folder by capture date.
Code Health & Issues
- HIGH - No test suite: The repository has 24 source files and zero test files. Any change ships without signal that existing behaviour is preserved, meaning regressions reach production undetected.
- HIGH - Push to default branch:
.github/workflows/appcast.ymlpermits pushes to the default branch. Automated commits land on the deploying branch without having run against the result, bypassing quality gates. - LOW - Missing workflow timeout: The GitHub Actions workflow declares no
timeout-minutes. A wedged step runs to the six-hour platform default, causing overlapping runs on a two-hourly schedule.
The Bottom Line
ImmiBridge functionalizes a niche need: syncing Apple Photos to Immich with incremental logic and Live Photo support on macOS. The codebase is structurally sound with no critical blocks, but it is hampered by a complete absence of tests and a CI configuration that pushes directly to the deploy branch. It is suitable for technically inclined macOS users already invested in the Immich ecosystem who are comfortable with the current maturity level and lack of automated test coverage.