FileFerry
FileFerry is a terminal-native local file transfer tool for people who want zero-config peer discovery, native QUIC transfers, resumable manifests, scriptable output, and TUI/daemon modes.
The goal is a single static binary named ferry for Linux, macOS, and
Windows that can:
- Discover nearby peers automatically on the local network.
- Send files and directories over a native QUIC fast path between
ferryinstances. - Receive transfers in foreground, TUI, or daemon mode.
- Provide clean human output by default and newline-delimited JSON when used from scripts.
FileFerry is early-stage. The repository currently contains native mDNS peer
discovery, direct-address and peer-targeted QUIC transfer, manifest-backed
skip/resume, a scriptable CLI, long-running daemon receive mode, an
interactive TUI send flow with trust confirmation and visible transfer errors,
foreground Ctrl+C transfer cancellation with partial-file cleanup,
crate metadata for crates.io publishing, release packaging automation, the
public website, and the remaining build plan in
BUILD.md.
The public project site is live at https://fileferry.app/.
A separate web send portal is planned for send.fileferry.app after the
native CLI, TUI, daemon, release, and documentation foundations are solid.
Why
Local file transfer tools proved that discovery, trust, and receiving files
can feel simple. ferry brings that simplicity to a fast, scriptable,
terminal-native workflow.
FileFerry fills that gap:
- Move large files between machines at LAN line rate.
- Use aliases, fingerprint prefixes, or direct addresses instead of copy-paste URLs.
- Run interactively when you want a file picker and transfer queue.
- Run quietly and predictably in scripts, SSH sessions, cron jobs, and headless machines.
Planned UX
JSON mode is designed for tools:
Each event will be emitted as one JSON object per line, including peer discovery, transfer start, progress, completion, rejection, and failure events.
Architecture
The project is one Cargo workspace with focused crates:
crates/
ferry-core/ protocol, transport, discovery, crypto, filesystem engine
ferry-cli/ clap CLI, progress output, JSON events, daemon commands
ferry-tui/ ratatui interactive interface
ferry-site/ public fileferry.app project website (Leptos + Axum SSR)
ferry-send-web/ future send.fileferry.app web portal
xtask/ build, release, benchmark, and packaging automation
ferry-site is self-contained: its CSS and favicon are embedded with
include_str!, it listens on plain HTTP at FERRY_SITE_ADDR (default
127.0.0.1:3000), and the Ubuntu + Caddy deployment is documented in
docs/site-deployment.md. The native ferry
binary does not depend on the site at runtime.
ferry-core owns all network, protocol, filesystem, discovery, trust, and
resume behavior. Frontends should stay thin.
Discovery
FileFerry will advertise and browse native peers with mDNS:
- Service:
_ferry._udp.local - TXT records: protocol version, transport support, fingerprint, alias, and ports
Discovered peers are unified into a single registry keyed by fingerprint. Aliases, hostnames, and fingerprint prefixes are lookup hints only.
Transport
Native ferry transfers use QUIC via quinn, with one transfer session per
connection, one stream per file, and a control stream for the manifest.
Transport selection is automatic:
- Discovered
ferrypeer: QUIC. - Direct address: QUIC.
Resume
Every transfer starts with a manifest containing session id, file entries, sizes, hashes, permissions where supported, and modification times.
The receiver compares the manifest against the destination:
- Existing matching file: skip.
- Matching partial file: resume from verified offset.
- Anything else: transfer from byte zero.
BLAKE3 is the planned hash because it is fast, parallel-friendly, and suitable for cheap prefix verification.
Trust
FileFerry uses trust-on-first-use for native peers:
- A persistent device key is generated on first run.
- Self-signed TLS certificates identify peers by public key fingerprint.
- First contact shows a short fingerprint for user confirmation.
- Known peers are pinned in the platform config directory.
ferry peers trustcan pin a full fingerprint or a discovered peer resolved by alias, hostname, or unique fingerprint prefix.- Optional PSK mode supports scripted and headless workflows.
Target Commands
ferry send <peer> <path>... Send files or directories
ferry recv [--accept-all] Receive in foreground
ferry recv --dest <dir> Receive into a specific directory
ferry peers List discovered peers
ferry peers trust <fingerprint> Trust a peer fingerprint
ferry peers forget <fingerprint> Remove a known peer
ferry daemon Run as a background receiver
ferry config Print or edit configuration
ferry version Print version information
ferry tui Force interactive TUI mode
Global flags:
--port <PORT> Override default listen port
--bind <IFACE> Bind to a specific interface
--json Emit newline-delimited JSON events
--no-discovery Disable discovery
--quiet, -q Reduce output
--verbose, -v Increase output
Planned exit codes:
0 success
1 generic error
2 peer not found
3 peer rejected transfer
4 transfer started but failed mid-flight
5 config or permission error
Configuration
ferry will use platform-native config directories through directories.
Example:
= "stephen-desktop"
= 53317
= 53318
= "~/Downloads/ferry"
= true
= false
= ["native"]
= 8
[]
= true
= ""
Web Roadmap
The first web surface should be the public project and marketing website at
fileferry.app. It should be built as early as practical with a Rust-first
stack, currently planned as Leptos with Axum for server-rendered pages,
hydration where useful, and shared Rust domain types where that stays clean.
The later web send portal at send.fileferry.app is a separate final-phase
product surface. It should take cues from tools like Wormhole, but must get
its own trust, relay, retention, abuse, and operating-cost design before any
hosted transfer capability ships.
Performance Targets
On commodity desktop hardware with NVMe storage and 1GbE:
- Single large file: at least 110 MB/s on the wire.
- Many small files, 10k files at 4KB each: at least 50 MB/s effective.
- Resume detection for a 50 percent complete 10GB file: under 5 seconds.
Tuning knobs should include QUIC congestion behavior, stream buffer size, hashing parallelism, chunk size, and concurrent files in flight.
Possible Future Work
- Compatibility bridge for third-party LAN transfer tools.
- Mobile companion app.
Development
The implementation plan lives in BUILD.md. The expected local
loop is:
The command package is prepared for crates.io as ferry-cli, which installs a
binary named ferry:
Tagged releases are built through cargo-dist for Linux, macOS, and Windows.
Crates are published in dependency order: ferry-core, ferry-tui, then
ferry-cli.
For docs-only changes, the narrow verification command is:
Durable implementation references now live under docs/, including
the current architecture, native protocol, discovery contract, security state,
daemon/headless notes, performance plan, release plan, and CLI/JSON examples.
License
MIT. See LICENSE.