Bidirectional sync for Internxt and OneDrive. Sparse placeholders. Move detection. Credential vault. Daemon mode with per-profile IPC. FUSE mount co-daemon. No Electron, no FUSE for sync itself.
Three-phase engine: Gather → Reconcile → Apply. Tracking-set design prevents the deletion-cascade bugs that plague state-db-as-authoritative approaches. Verified against 195 000-file Internxt accounts and 3 000-file OneDrive accounts.
Files appear at full reported size immediately. Zero disk blocks consumed until the file is opened. Implemented via setLength() on a sparse file — no FUSE, no kernel module required for sync.
Renames and moves are detected by remote ID, not just path. Server-side move operations are used where the provider supports them — no re-upload, no wasted bandwidth.
OAuth tokens and credentials stored with AES-256-GCM encryption. Passphrase-protected. Set UNIDRIVE_VAULT_PASS for unattended daemon use.
One long-lived JVM daemon per profile. Strictly reactive — no background polling loops. Refresh triggered explicitly via RPC. Unix domain socket for IPC at /run/user/{uid}/unidrive-{profile}.sock. Process-lock prevents duplicate instances.
The unidrive-mount co-daemon mounts your cloud as a POSIX filesystem. Read + write-through. FUSE_PASSTHROUGH for zero-userspace reads on hydrated files. Requires Linux kernel ≥6.9 and libfuse ≥3.16.
Every conflict creates a timestamped archive copy before overwrite. JSONL conflict log. Destructive-overwrite protection via keep_overwritten archive mode for Internxt.
Internxt enumeration checkpoints survive daemon restarts. A session killed mid-crawl of a 200 000-file account resumes from where it stopped, not from scratch.
Remote pages are processed as they arrive. No need to buffer the full remote listing before deciding what to sync. Keeps memory flat on large accounts.
create / mknod not yet implemented — creating new files through the mount returns ENOSYS./gradlew installDistAdditional providers are planned. The provider SPI is stable — contributions welcome.
The daemon owns no sync loop. It waits for an explicit refresh.run RPC call. This keeps the process quiet between syncs and makes lifecycle predictable.
FileChannel advisory lock prevents two daemon instances from racing on the same profile. Mode-mutex enforces that sync and mount don’t run simultaneously.
Unix domain socket at /run/user/{uid}/unidrive-{profile}.sock. Used by the CLI, the mount co-daemon, and any external consumer (scripts, status bars).
10-second shutdown window. In-flight transfers are allowed to finish. IPC server closes after active handlers complete.
10s windowThe daemon holds the OAuth session and credential vault. Token refresh happens inside the daemon process, not in short-lived CLI invocations.
AES-256-GCMEvery conflict is logged to a JSONL file. Timestamped archive copies are kept before overwrite. Inspect via unidrive conflicts.
$ socat - UNIX-CONNECT:/run/user/$(id -u)/unidrive-onedrive.sock
{"event":"sync_start","profile":"onedrive","ts":"2026-05-25T08:15:00Z"}
{"event":"download","profile":"onedrive","path":"Photos/vacation.jpg","size":5242880}
{"event":"upload","profile":"onedrive","path":"Documents/report.pdf","size":204800}
{"event":"sync_complete","profile":"onedrive","duration_s":23,"downloaded":1,"uploaded":1,"errors":0}
Remote delta streamed page-by-page → compared against local tracking-set in SQLite
Move detection, conflict policy, case collisions, pin rules, tracking-set predicate evaluation
Parent-directory operations first, then concurrent size-bucketed transfers
The tracking-set engine replaces the old state-db-as-authoritative model. Phantom-row deletion bugs — where a file that never existed locally gets deleted remotely — are structurally prevented. Verified in a 62-minute end-to-end run against a real 195 740-file Internxt account: zero unexpected deletes.
Linux kernel ≥6.9 (FUSE_PASSTHROUGH support) and libfuse ≥3.16. The binary refuses to start on older kernels with exit code 78.
kernel ≥6.9Hydrated files: served via FUSE_PASSTHROUGH with zero userspace copies. Placeholder files: fetched from cloud, written to ~/.cache/unidrive/hydration/, then served.
Writes go through userspace to the JVM daemon over IPC. The daemon queues the upload. fsync triggers durability confirmation.
write-throughlookup, readdir, open, read, write, fsync, mkdir, unlink, rmdir, rename (with inode preservation). File creation (create/mknod) not yet implemented.
flock on the profile lock file prevents two mount instances from racing on the same profile. Integrates with the JVM daemon’s mode-mutex.
safeThe mount does not automatically reconnect after the JVM daemon restarts. You must unmount and remount manually. Fix is tracked in the backlog.
manual remount# Start the JVM daemon first unidrive daemon start -p onedrive # Mount your cloud folder (Rust co-daemon, kernel ≥6.9 required) unidrive mount ~/cloud -p onedrive # Files appear as placeholders immediately; hydrated on open ls ~/cloud/ ls: Photos/vacation.jpg Documents/report.pdf ... # Unmount fusermount3 -u ~/cloud
# Authenticate with your Internxt credentials unidrive -p internxt auth # Preview what will sync (dry run) unidrive -p internxt sync --dry-run # Sync — sparse placeholders, zero disk until opened unidrive -p internxt sync # Start the daemon, then trigger a sync via IPC unidrive daemon start -p internxt unidrive -p internxt refresh
Kotlin/Jetpack Compose. Shares the core sync engine via Gradle composite build. SFTP and OneDrive wired. Early alpha.
| Tool | Bidir Sync | Placeholders | Move Detect | Multi-Provider | Credential Vault | OSS | Price |
|---|---|---|---|---|---|---|---|
| UniDrive pre-release | ✓ 3-phase | ✓ sparse | ✓ by ID | 2 (Internxt, OneDrive) | ✓ AES-256-GCM | ✓ | Free |
| rclone | bisync stable | ✗ | ✗ | ✓ 70+ | ✗ | ✓ | Free |
| Syncthing | ✓ | ✗ | ✗ | P2P only | ✗ | ✓ | Free |
| Insync | ✓ | ✗ | ✗ | 3 only | ✗ | ✗ | ~$30 |
| Dropbox | ✓ | ✗ Linux | ✓ | 1 only | ✗ | ✗ | $12/mo |
| Nextcloud | ✓ | experimental | ✗ | 1 only | ✗ | ✓ | Free |
✓ = yes ✗ = no ~ = partial Data as of May 2026. UniDrive row reflects pre-release v0.0.1.
See full comparison ↓Side-by-side across open source, freemium, and proprietary solutions. UniDrive row reflects pre-release state.
| Tool | License | Price | Providers | Bidir Sync | Placeholders | Move Detect | Conflicts | Credential Vault | Delta Sync | Pin / Selective | CLI | GUI |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| UniDrive pre | OSS | Free | 2 (Internxt, OneDrive) | ✓ 3-phase | ✓ sparse | ✓ by ID | ✓ archive copy | ✓ AES-256-GCM | partial (OneDrive cursor not persisted) | pin rules planned | ✓ | planned |
| rclone | MIT | Free | 70+ | bisync (stable 2025) | ✗ FUSE mount | ✗ | basic | ✗ | partial | filters | ✓ | web UI |
| Syncthing | MPL-2 | Free | P2P only | ✓ | ✗ | ✗ | ✓ | ✗ | ✓ block-level | ✓ ignore | ✓ | ✓ web |
| Nextcloud | GPLv2 | Free | Nextcloud only | ✓ | experimental | ✗ | basic | ✗ | ✓ | ✓ selective | nextcloudcmd | ✓ Qt |
| ownCloud | GPLv2 | Free | ownCloud only | ✓ | ✓ VFS | ✗ | basic | ✗ | ✓ | ✓ selective | owncloudcmd | ✓ Qt |
| onedrive (abraunegg) | GPLv3 | Free | OneDrive only | ✓ | ✗ | ✗ | basic | ✗ | ✓ delta API | ✓ skip_dir | ✓ | ✗ |
| Maestral | MIT | Free | Dropbox only | ✓ | ✗ | ✗ | ✓ | ✗ | ✓ longpoll | ✓ gitignore | ✓ | ✓ tray |
| FreeFileSync | GPLv3 | Free | local/FTP/SFTP | ✓ manual | ✗ | ✓ | ✓ | ✗ | comparison | ✓ filters | batch | ✓ |
| Internxt CLI | OSS | Freemium | Internxt only | ✗ manual | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ |
| Internxt Desktop | OSS | Freemium | Internxt only | FUSE write-back | FUSE mount | ✗ | byte compare | ✗ | ✗ full poll | ✗ | ✗ | ✓ Electron |
| Dropbox | Proprietary | Freemium | Dropbox only | ✓ | ✗ Linux | ✓ | ✓ | ✗ | ✓ block-level | ✓ selective | ✓ | ✓ |
| MEGA | Custom | Freemium | MEGA only | ✓ | ✗ | ✗ | basic | ✗ | ✓ | ✓ selective | ✓ mega-cmd | ✓ |
| pCloud | Proprietary | Freemium | pCloud only | ✓ | ✓ FUSE vdrive | ✗ | basic | ✗ | ✓ block-level | ✓ selective | pfs CLI | ✓ |
| Tresorit | Proprietary | from $4.75/mo | Tresorit only | ✓ | ✗ | ✗ | basic | ✗ | ✓ | ✓ selective | ✓ | ✓ |
| Insync | Proprietary | ~$30/acct | GDrive, OneDrive, Dropbox | ✓ | ✗ | ✗ | basic | ✗ | ✓ | ✓ selective | ✓ headless | ✓ Qt |
| ExpanDrive | Proprietary | Free personal | 20+ | ✗ mount only | ✓ net mount | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ |
✓ = full support partial/limited ✗ = no support Data as of May 2026.
Most cloud tools can’t show files without downloading them. Here’s the 2026 landscape.
| Tool | Placeholder / on-demand files on Linux | Mechanism |
|---|---|---|
| UniDrive | ✓ Pre-release | Sparse files via setLength() — zero disk blocks, real size in stat. FUSE mount adds on-demand hydration (kernel ≥6.9). No kernel module for sync itself. |
| ownCloud | ✓ Stable | Qt VFS layer with file manager integration (Nautilus, Dolphin). |
| pCloud | ✓ Stable | FUSE virtual drive — files fetched on open. Requires FUSE kernel module. |
| ExpanDrive | ✓ Network mount | Network filesystem mount. Files not available offline. Proprietary. |
| rclone mount | Approximation | FUSE mount with VFS cache modes. Not integrated into file manager. Requires FUSE. |
| Nextcloud | Experimental | VFS on Linux is marked experimental. Stability issues and data loss bugs reported in 2026. |
| Dropbox | ✗ Win/Mac only | Linux client lacks Smart Sync. Selective sync only (invisible if not synced). |
| Everyone else | ✗ | Syncthing, MEGA, Maestral, Insync, Tresorit, abraunegg/onedrive — no placeholder support. |
setLength()