Skip to content
highercomvePublic

About

Personal distributed filesystem in Zig: share folders across your devices, files download on demand, a writable swarm folder and a FUSE mount.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

NomadFS — personal device mesh & virtual filesystem for roaming devices

Your files roam with you.

Personal device mesh & virtual filesystem for roaming devices

Built with Zig & Oriel by foreachdeveloper

NomadFS

NomadFS is a private, distributed filesystem and device mesh written in Zig 0.16. It connects laptops, desktops, phones, and servers into a secure peer-to-peer storage mesh. Share folders across devices with instant metadata and on-demand streaming, collaborate via a CRDT-replicated swarm folder, and mount your mesh directly into your operating system with FUSE.

All core features are verified on real hardware: Linux desktops, Android phones and a Chromebook, with Windows and macOS built and tested in CI.

Download: the latest release has the app for Android (APK, or Google Play testing), Linux (AppImage, deb, rpm), Windows (installer) and macOS (Apple silicon, .dmg), and the nomadfs CLI for Linux, Windows and macOS. Docs: nomadfs.foreachdeveloper.com.

Install from a terminal (the app and the CLI for your user, every file checked against the release's checksums; the app then updates itself, and the CLI with nomadfs --upgrade):

# Linux and macOS (Apple silicon): Linux puts the AppImage and the CLI in
# ~/.local/bin with a launcher entry; macOS puts NomadFS.app in /Applications
# and the CLI in ~/.local/bin
curl -fsSL https://raw.githubusercontent.com/highercomve/nomadfs/main/scripts/install.sh | bash
# Windows (PowerShell): runs the app's installer silently and puts nomadfs.exe
# on your PATH
irm https://raw.githubusercontent.com/highercomve/nomadfs/main/scripts/install.ps1 | iex

VERSION=0.3.17 ($env:VERSION = '0.3.17' on Windows) installs a given release; NO_CLI=1 and NO_RESTART=1 skip the CLI or starting the app; NO_DESKTOP=1 skips the Linux launcher entry.


Key Features

Shared Folders (On-Demand Streaming & Filestore)

  • Instant visibility: Share any local folder (--share Name:/path or in config); every paired device sees the complete directory listing immediately.
  • On-demand streaming: File bytes are never bulk-transferred ahead of time. Range reads fetch only the specific blocks requested by the application reading the file.
  • Zero data duplication (Filestore): Shared files are not copied into the local block store. Leaf chunks are served directly from the source files on disk.
  • Read integrity: Leaves are re-hashed against their Content Identifiers (CIDs) on every read. Modified files fail matching rather than serving stale or corrupted data.
  • Background indexing: Folders are indexed and monitored asynchronously without blocking node operations.

Swarm Folder (Conflict-Free Collaborative Folder)

  • Shared read/write space: A global folder where any authorized device in the swarm can create, edit, rename, and delete files.
  • CRDT replication: Folder manifests are replicated as state-based CRDTs with Lamport logical clocks and version histories, converging deterministically across all nodes.
  • Conflict preservation: Concurrent edits to the same path are preserved rather than overwritten—the higher version keeps the path while the competing version is renamed to name (conflict from <device>).ext.
  • Edit precedence: Concurrent edits always win over deletes. Deletes propagate as tombstones.
  • Distributed content fetching: File content remains on the author's device and is pulled on demand by peers, after which any caching peer can serve it.
  • Backup devices: A desktop or server with swarm_backup = true (--swarm-backup, or Settings → Swarm backup in the app) keeps a copy of every file, so the folder stays readable while the device that added a file is offline.
  • No mount needed: the running node (the app or a service) serves the swarm folder to local programs over a small HTTP API on 127.0.0.1, under a random token it writes to <device dir>/api.json (mode 0600, removed on exit). Only your user can call it: the token file is yours alone, and on Linux and macOS the node also checks that each connection comes from the node's user. Every file carries its content id as an ETag; PUT with If-Match: "<etag>" or If-None-Match: * and DELETE with If-Match are conditional, and answer 412 when the file changed. nomadfs swarm is its command-line client, and Locket uses it to share a secrets vault between your devices.

Desktop Mount (Linux FUSE)

  • Direct kernel protocol: Speaks the FUSE kernel protocol on /dev/fuse directly (no libfuse), mounting unprivileged through fusermount3.
  • Remote shares (<mount>/<device>/<share>/...): Read-only browsing with on-demand chunk streaming and local block caching for offline resilience.
  • Swarm mount (<mount>/Swarm): Fully writable folder supporting file creation, writes, mkdir, unlink, rmdir, and rename.
  • Editor compatibility: Supports atomic save routines (write temporary file followed by rename).
  • CLI & daemon: Run via nomadfs --mount <dir>.

Desktop Mount (macOS and Windows WebDAV)

  • No driver: A WebDAV server on 127.0.0.1 shows the same folders, mounted by the system's own client (mount_webdav on macOS, net use and the WebClient service on Windows).
  • Same layout: <mount>/<device>/<share>/... read-only, <mount>/Swarm read and write (copy, rename, delete, folders). Finder's and Explorer's metadata files stay in memory, out of the swarm.
  • Private to you: A random token in the address, new each start; requests naming another host are refused; on macOS and Linux only your own user's programs are served.
  • CLI: nomadfs --mount ~/NomadFS (macOS), nomadfs --mount Z: (Windows), or nomadfs --webdav <port> to serve without mounting.

One-Time Invites & Mutual Trust

  • Zero-leak pairing: Join devices to a swarm without exposing or copy-pasting the master swarm key.
  • Time-limited single-use tokens: Invites generate a URI (nomadfs://invite?addr=..&token=..) with a 128-bit random token expiring after 10 minutes.
  • Noise XXpsk0 security: Both devices derive a pre-shared key from the token and perform a Noise_XXpsk0 handshake with ephemeral keys.
  • Ticket exchange: Devices swap signed pairing tickets inside the encrypted tunnel, mutually registering cryptographic identities and trust before exchanging the swarm key.
  • QR code workflows: Invites display as terminal and GUI QR codes; the Android app scans them directly with the device camera.

NomadFS App (nomadfs-gui)

Built with Oriel as a lightweight native desktop and mobile application:

  • Platforms: Linux, Windows and macOS desktops, and Android (smartphones, tablets, and Chromebooks). The mount works on all three desktops.
  • Remote browsing: Browse shares across all online devices with responsive tree views.
  • In-app previews: View images, stream audio and video, view PDFs, and inspect text files without saving them locally first.
  • Downloads: Download individual files or directory trees directly to local storage.
  • Local shares: Pick and share host folders using the system folder picker.
  • Mount management: Dedicated Mount tab and system tray icon to keep the mount (FUSE on Linux, WebDAV on macOS and Windows) running in the background when the main window is closed.
  • Connect & QR scanner: Display swarm invites as QR codes and scan incoming invites with the camera.
  • Text Drop: Share quick notes and text snippets addressed by CID across devices.
  • Device management: Inspect trusted peers and revoke access with a single click, and rotate the swarm key for every trusted device.
  • Background on Android: An optional "keep running" mode (a foreground service with a notification) keeps the phone reachable and the swarm folder syncing after you leave the app.

Core Architecture

  • Content-addressed storage: Merkle DAG representation using FastCDC content-defined chunking; every block is addressed by its SHA-256 hash.
  • Discovery & routing: Kademlia DHT for decentralized peer discovery and addressing.
  • Encrypted transport: Native persistent TCP connections secured with the Noise Protocol Framework (XXpsk0 / IK) and multiplexed with Yamux streams.
  • Identity & trust: Ed25519 and X25519 pinned identities with local revocable trust stores.
  • Mobile C ABI: Unified C API (src/mobile/api.zig) providing the foundation for Android JNI and Oriel GUI bindings.

CLI Usage

# Start node and mount shares to a local directory
nomadfs --mount /mnt/nomadfs --share Photos:/home/user/Pictures

# Generate a 10-minute one-time invite with QR code
nomadfs --invite

# Display pairing ticket for manual pairing
nomadfs --pair

# Trust a device pairing ticket
nomadfs --trust "nomadfs://pair?..."

# List trusted devices
nomadfs --devices

# Revoke a device's trust
nomadfs --revoke <device-id-or-fingerprint>

The swarm folder from the command line, through the running node (no mount):

nomadfs swarm status                      # the swarm folder's state
nomadfs swarm ls [dir]                    # names, sizes and etags (JSON)
nomadfs swarm get notes/todo.md           # a file, on stdout
nomadfs swarm put notes/todo.md [file]    # from the file, or stdin; prints the new etag
nomadfs swarm put notes/todo.md --if-match <etag>   # only over that version
nomadfs swarm put notes/new.md --create   # only where nothing is yet
nomadfs swarm rm notes/old.md [--if-match <etag>]

Build

Prerequisites

  • Zig 0.16.0
  • Linux: fusermount3 (for FUSE mounting)

Core Library & CLI

# Build the CLI binary (zig-out/bin/nomadfs)
zig build

# Run unit tests
zig build test

Install from source (Linux)

# Build the app's AppImage and the CLI, install them to ~/.local/bin with a
# launcher entry, and restart the app
scripts/install-local.sh

NO_RESTART=1 scripts/install-local.sh     # leave the app stopped
ORIEL_FORK=../oriel scripts/install-local.sh  # build against a local Oriel

Desktop App (nomadfs-gui)

The app uses Oriel v0.20.7, which zig build fetches.

cd nomadfs-gui

# Build desktop application (zig-out/bin/nomadfs-gui)
zig build

# Run GUI command tests
zig build test

Android App

cd nomadfs-gui

# Build the Android binary via Oriel
zig build -Dtarget=aarch64-linux-android

# Package APK using Gradle
cd android
./gradlew assembleDebug

About

Personal distributed filesystem in Zig: share folders across your devices, files download on demand, a writable swarm folder and a FUSE mount.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages