Skip to main content
Passing a directory to hayate send works exactly like passing a single file — Hayate handles the packaging, compression, and extraction transparently on both sides. Under the hood, the directory is streamed as a tar archive in real time, so no temporary file is written to disk before the transfer starts. The receiver extracts the archive directly into your chosen output directory with the same name as the source.

Basic Directory Transfer

Run hayate send with a directory path on the sender and hayate receive with --output on the receiver. Both sides need to use the same code phrase in Pairing Mode, or the sender needs to target the receiver’s IP and port in Direct Mode.
After the transfer completes, you’ll find ./downloads/my-project/ on the receiver — matching the top-level directory name from the sender.

How It Works Under the Hood

Understanding the pipeline helps you make good choices about compression and troubleshooting.
1

Tar streaming

Hayate walks the source directory and writes a tar archive directly into an in-memory stream. No temporary .tar file is created on the sender’s disk — the archive is built on the fly as bytes are consumed.
2

Compression and encryption

The raw tar byte stream is compressed with Zstd (level 1 by default), then split into frames. Each frame is encrypted with AES-256-GCM (hardware-accelerated) or ChaCha20-Poly1305 and sent over a QUIC stream.
3

Streaming extraction

The receiver decrypts and decompresses each frame as it arrives, then feeds the resulting bytes into a streaming tar extractor. Entries are written to the output directory progressively — you start seeing files appear before the transfer has finished.
4

Integrity verification

Once all frames arrive, Hayate compares the stream checksum (Blake3 by default) computed on both sides. A mismatch causes the transfer to fail with an error rather than silently saving corrupt data.

Security During Extraction

Hayate applies strict validation to every entry in the tar archive before writing it to disk.
Malicious tar archives can contain entries with paths like ../../etc/crontab designed to escape the output directory and overwrite arbitrary files. Hayate rejects these entries outright. Never disable or bypass this validation when accepting archives from untrusted sources.

Large Directory Transfers

For directories full of already-compressed files (videos, images, ZIP archives), disabling compression avoids wasting CPU cycles recompressing data that won’t shrink further.
Use --hash sha256 alongside --compress=false if you want a widely-recognised checksum format for the transfer log.

Nested Directories

Hayate preserves the full directory structure. A source tree like:
is extracted to the output directory with the same layout intact:
Empty directories are included in the archive and reproduced on the receiver.
For large transfers where you want maximum predictability and don’t need auto-discovery, use Direct Mode with an explicit IP and port. It eliminates the mDNS discovery step, removes the pairing timeout, and lets the receiver stay up indefinitely waiting for the sender.