Gaps & Known Issues

Dropbear is pre-1.0. This page is the honest list of what isn't done, what's known-broken, and what's deliberately out of scope for now. It's distinct from Failure Modes, which covers things Dropbear is designed to handle gracefully — this page is the stuff that's still rough.

No installer / automatic bootstrap yet

There is no packaged installer — no signed .app bundle or .dmg, no .pkg, no .deb/.rpm, no Homebrew formula. You build the binary yourself.

dropbear daemon install does write and activate a per-user service (a systemd user unit on Linux, a launchd LaunchAgent on macOS) and drops a commented-out starter daemon.toml, but that's service registration, not distribution. Standing up a new device still means: get the binary onto the machine, set the DROPBEAR_S3_* credentials in the environment, and dropbear register (or hand-fill a [roots.init] block so the daemon self-bootstraps the root on first run). None of that is one-click.

The desktop tray's start/stop toggle now drives the daemon directly through the OS service manager (launchctl on macOS, systemctl --user on Linux), so it is no longer a stub — but it still requires the service to have been installed first with dropbear daemon install, so it doesn't remove the bootstrap steps above. "v1.0 is when the bootstrap story stops being rough" remains the bar.

macOS file-watcher exhausts file descriptors on large trees — Fixed

This gap is closed. The daemon now uses a native FSEvents backend on macOS (//go:build darwin). FSEvents watches a root path recursively in a single call, holding no per-file or per-directory descriptors. lsof confirms the fd count stays constant regardless of how many files are under the root. The kqueue/fsnotify backend — which opened one fd per watched directory and could exhaust ulimit -n (256 by default) on a large tree — is still used on Linux and other platforms where it is not a problem.

The fix is in internal/fswatch as of the macos-fsevents-hint-backend change. Watcher wakeups remain non-authoritative hints backed by the interval and head-poll backstop, so correctness is unchanged.

No iOS client

There's an Android viewer (see Mobile Client), but no iOS equivalent. iOS's sandboxing — no arbitrary filesystem access, no persistent background daemon, no user-controlled xattrs, files reached only through abstractions like the Files app — makes even a read-only client a much heavier lift than on Android, and it isn't built yet.

Manifest file is unoptimized

Each device publishes a single manifest.json that is a full snapshot of every tracked path — relative path, mode, size, hash, symlink target, and so on for the whole root — and it is rewritten and re-uploaded in full on every sync, even when one file changed. (This is a deliberate MVP choice; full snapshots are simple to reason about and trivial to verify against the bucket — see the manifest-full-snapshots and single-manifest-layout ADRs.)

The cost shows up on big roots: a manifest for hundreds of thousands of entries is a large JSON object, re-serialized and re-PUT on each sync, and re-fetched by every peer that notices a new head. There's no compression, no delta encoding, and no chunking yet. Candidate directions — none implemented:

  • compress the manifest on the wire and at rest;
  • publish deltas against a base manifest instead of a full snapshot every time;
  • split very large roots into chunked manifests so a small change touches a small object.

If your root is enormous and changes constantly, the manifest is currently the most likely thing to feel heavy.