Cloud sync for Linux.
Pre-release. Open source.

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.

v0.0.1 · pre-release · Kotlin · JDK 21+ · Apache 2.0 · 13 modules
What works today

Built for the gaps others leave open

Bidirectional Sync

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.

Sparse Placeholders

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.

Move Detection

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.

🔒

Credential Vault

OAuth tokens and credentials stored with AES-256-GCM encryption. Passphrase-protected. Set UNIDRIVE_VAULT_PASS for unattended daemon use.

Daemon + Per-Profile IPC

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.

📁

FUSE Mount

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.

📄

Conflict Handling

Every conflict creates a timestamped archive copy before overwrite. JSONL conflict log. Destructive-overwrite protection via keep_overwritten archive mode for Internxt.

🔄

Resumable Scans

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.

📈

Streaming Reconciliation

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.

⚠ Known gaps — pre-release

Providers

Two providers. Both fully integrated.

Microsoft OneDrive Microsoft Graph API. Delta-cursor change detection. Hard and soft delete semantics. Upload-session retry with expiry handling. OAuth2
🔒 Internxt Drive End-to-end encryption native to the provider. Per-file AES-GCM keys. WebSocket change notifications. Resumable scan checkpoints. Parallel pagination. E2EE native

Additional providers are planned. The provider SPI is stable — contributions welcome.

Daemon Mode

One daemon per profile, strictly reactive

Strictly Reactive

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.

no polling

Per-Profile Process Lock

FileChannel advisory lock prevents two daemon instances from racing on the same profile. Mode-mutex enforces that sync and mount don’t run simultaneously.

safe

IPC Socket

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).

socat-ready

Graceful Shutdown

10-second shutdown window. In-flight transfers are allowed to finish. IPC server closes after active handlers complete.

10s window

Auth Session Owner

The daemon holds the OAuth session and credential vault. Token refresh happens inside the daemon process, not in short-lived CLI invocations.

AES-256-GCM

Conflict History

Every conflict is logged to a JSONL file. Timestamped archive copies are kept before overwrite. Inspect via unidrive conflicts.

JSONL log

Monitor daemon via IPC

$ 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}
Under the Hood

Three-phase sync engine

① Gather

Collect

Remote delta streamed page-by-page → compared against local tracking-set in SQLite

② Reconcile

Decide

Move detection, conflict policy, case collisions, pin rules, tracking-set predicate evaluation

③ Apply

Execute

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.

FUSE Mount

unidrive-mount — your cloud as a filesystem

Hard Requirements

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.9

Read Path

Hydrated files: served via FUSE_PASSTHROUGH with zero userspace copies. Placeholder files: fetched from cloud, written to ~/.cache/unidrive/hydration/, then served.

zero-copy reads

Write Path

Writes go through userspace to the JVM daemon over IPC. The daemon queues the upload. fsync triggers durability confirmation.

write-through

Operations Implemented

lookup, readdir, open, read, write, fsync, mkdir, unlink, rmdir, rename (with inode preservation). File creation (create/mknod) not yet implemented.

POSIX subset

Profile Lock

flock on the profile lock file prevents two mount instances from racing on the same profile. Integrates with the JVM daemon’s mode-mutex.

safe

Known Limitation

The mount does not automatically reconnect after the JVM daemon restarts. You must unmount and remount manually. Fix is tracked in the backlog.

manual remount

Mount your cloud

# 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
Provider Spotlight

Sync Internxt on Linux — the missing client

# 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

UniDrive Android — same engine, Android-native

Kotlin/Jetpack Compose. Shares the core sync engine via Gradle composite build. SFTP and OneDrive wired. Early alpha.

See Android →
Comparison

How UniDrive stacks up

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 ↓
Full Tool Comparison

Feature comparison // Linux sync tools

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.

The placeholder gap on Linux

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.

Where UniDrive wins and where it doesn’t // honest take

UniDrive advantages

  • Only multi-provider tool with true bidirectional sync + sparse placeholders on Linux
  • Tracking-set engine structurally prevents phantom-row deletion bugs
  • Move detection uses remote IDs — no re-upload on rename
  • Streaming reconciliation keeps memory flat on large accounts
  • Resumable Internxt scans survive daemon restarts mid-crawl
  • No FUSE for sync itself — sparse files via setLength()
  • FUSE mount co-daemon for filesystem access (kernel ≥6.9)
  • Per-profile daemon with explicit lifecycle — no surprise background activity
  • Credential vault with AES-256-GCM
  • Destructive-overwrite protection with archive copies

Where alternatives are stronger

  • rclone: 70+ providers vs 2. Massive community. Stable FUSE mount. Mature.
  • Syncthing: Block-level delta sync. P2P with no cloud dependency.
  • Dropbox / MEGA: Block-level sync. Mature file manager integration.
  • Nextcloud / ownCloud: Native Qt GUI with file manager overlay icons.
  • Insync: Polished multi-provider GUI with headless mode. Proven at scale.
  • Pre-release — known bugs including FUSE create and mount reconnect
  • No release tarball — build from source only
  • No GUI — CLI-only
  • No block-level delta — full file transfers even for small changes
  • JVM startup overhead vs native Go/C++ tools (mitigated by daemon mode)

Best fit for these cases

  • You use Internxt or OneDrive on Linux and want real bidirectional sync → UniDrive
  • You want placeholder files on Linux without FUSE for sync → UniDrive
  • You want zero-knowledge E2EE with Internxt from a real sync engine → UniDrive
  • You need maximum provider coverage (70+) → rclone
  • You want P2P without any cloud → Syncthing
  • You need a polished GUI today → Insync or native clients