Hayate (はやて)
Encrypted, compressed, blazing-fast cross-device file transfer for local networks, terminals, and Termux.
__ __ _____ __ __ _____ _______ _____
/\_\ /_/\ /\___/\ /\ /\ /\ /\___/\ /\_______)\ /\_____\
( ( (_) ) ) / / _ \ \\ \ \/ / // / _ \ \\(___ __\/( (_____/
\ \___/ / \ \(_)/ / \ \__/ / \ \(_)/ / / / / \ \__\
/ / _ \ \ / / _ \ \ \__/ / / / _ \ \ ( ( ( / /__/_
( (_( )_) )( (_( )_) ) / / / ( (_( )_) ) \ \ \ ( (_____\
\/_/ \_\/ \/_/ \_\/ \/_/ \/_/ \_\/ /_/_/ \/_____/
Swift File Transfer | Secure, Encrypted, & Compressed
Hayate is a zero-config, high-performance CLI for sending files and directories between machines on a local network. Built on QUIC via compio-quic and quinn-proto, with completion-based asynchronous I/O (io_uring on Linux/Android, IOCP on Windows, kqueue on macOS), Hayate is designed to keep fast Wi-Fi and Ethernet links saturated without sacrificing safety.
✦ Features
- Authenticated Encryption: Ephemeral
X25519key exchange (DH) andChaCha20-Poly1305AEAD payload encryption. - Proactor Async Engine: Driven by
compiothread-per-core runtime for zero-cost async I/O. - Terminal-Safe Progress: Enabled by default, with transfer rate, ETA, elapsed time, and connection/pairing spinners that behave consistently across desktop terminals and Termux.
- Zero-Config Pairing: Secure LAN pairing utilizing random code-phrase broadcasters—no manual IP swapping required.
- Hardware Hashing: Hashing utilizing
ring::digesthardware-accelerated SHA-256 for integrity verification. - Smart Compression: Concurrent
zstdlevel 1 compression that automatically skips pre-compressed file extensions (e.g.,.zip,.mp4,.png). - Direct Mode: Support for direct peer connections via IPv4 and IPv6 (including bracketed IPv6 syntax like
[fd00::1]:50001). - Cross-Platform: Binary packages for macOS, Linux, Windows, and Android (Termux).
✦ CLI Experience
Hayate keeps normal commands focused on the active transfer. The banner is shown only for help-oriented entry points:
During transfers, Hayate shows connection and pairing spinners followed by a terminal-safe progress bar:
⠋ [00:00:04] [==============================>---------] 1.15 GiB/1.46 GiB (78%) 14.2 MiB/s ETA 22s
- Consistent Output:
send,receive, anddiscoverstart directly with useful status lines instead of repeating the banner. - Steady Tick: Spinners animate at a steady cadence while connecting, pairing, or transferring.
- Headless Friendly: Suppress visual indicators with
--no-progressor the--no-tuialias. - Receiver Lifecycle:
hayate receiveexits after one successful transfer, but keeps listening after failed connections, failed handshakes, rejected transfers, or dropped transfers.
✦ Quick Start
1. Pairing Mode
Use code-phrase pairing when you do not want to exchange IP addresses manually.
On the Receiver:
On the Sender:
Hayate scans the local network, pairs the nodes with the shared code phrase, performs the key exchange, and transfers the payload.
2. Direct Mode
Specify the receiver address directly to skip pairing broadcasts.
On the Receiver:
On the Sender:
You can also pass the target positionally:
Use either positional TARGET or --peer, not both.
✦ CLI Command Reference
Run hayate or hayate --help for the top-level help menu. Normal commands do not print the banner; help commands do.
hayate receive
Starts a receiver and waits for one incoming file or directory. After a successful receive it exits. If a connection attempt fails, the receiver reports the error and keeps listening.
Aliases: recv, rx
Usage: hayate receive [OPTIONS]
Options:
-b, --bind <BIND> IP address to bind the QUIC listener [env: HAYATE_BIND=] [default: 0.0.0.0]
-p, --port <PORT> Port to listen on [env: HAYATE_PORT=] [default: 50001]
-o, --output <OUTPUT> Directory to save received files into [default: .]
--auto-accept Auto-accept all incoming transfers without prompting
--no-progress Suppress the progress bar and spinner output
--code <CODE> Cryptographic code-phrase for pairing
-h, --help Print help
hayate send
Sends a file or directory to a receiver.
Alias: tx
Usage: hayate send [OPTIONS] <PATH> [TARGET]
Arguments:
<PATH> Path to the file or directory to send
[TARGET] Receiver address in the form ip:port or hostname:port
Options:
--peer <PEER> Receiver address in the form ip:port or hostname:port (compat option)
--code <CODE> Cryptographic code-phrase for pairing
-z, --compress Compress chunks with zstd level 1 before encrypting
--no-progress Suppress the progress bar and spinner output
-h, --help Print help
TARGET and --peer are mutually exclusive. If neither is supplied, Hayate generates a pairing code and waits for a receiver using hayate receive --code "<code>".
hayate discover
Scans the local network subnet for active receivers.
Alias: scan
Usage: hayate discover [OPTIONS]
Options:
-t, --timeout <TIMEOUT> Network scan timeout in seconds [default: 3]
--cidr <CIDR> Override the subnet CIDR to scan (e.g. 192.168.1.0/24)
-h, --help Print help
✦ Security Threat Model
A common question is: Why does Hayate encrypt payloads using ChaCha20-Poly1305 if QUIC already encrypts all traffic via TLS 1.3?
- Unauthenticated TLS: Hayate uses self-signed ephemeral certificates generated dynamically. Because there is no PKI or Certificate Authority (CA) verifying these certificates on a local network, standard TLS is vulnerable to Man-in-the-Middle (MITM) spoofing attacks.
- Cryptographic Channel Binding: To prevent MITM attacks, Hayate derives a shared key by salting a Diffie-Hellman key exchange with the user's code-phrase.
- Payload Protection: If an attacker intercepts the connection, they cannot decrypt the metadata or payload frames without knowing the code-phrase. The application-layer encryption acts as an authenticated channel-binding mechanism.
✦ Termux (Android) Usage
Android can limit multicast and broadcast discovery depending on device and network policy. Direct IP connections are the most reliable option:
On Phone (Receiver):
On Computer (Sender):
--no-progress is recommended for scripted Termux runs or terminals that do not redraw progress output reliably.
✦ Installation
You can install Hayate instantly using the automated installation scripts:
macOS, Linux, and Termux (bash)
Run the following command to download and install the latest binary to /usr/local/bin (or $PREFIX/bin in Termux):
|
Source code: scripts/install.sh
Windows (PowerShell)
Run the following command in PowerShell to download and install the Windows executable:
irm https://raw.githubusercontent.com/ShiinaSaku/Hayate/refs/heads/master/scripts/install.ps1 | iex
Source code: scripts/install.ps1
Manual Installation
Alternatively, you can manually download and configure precompiled binaries from the Releases page.
✦ Building from Source
Requirements
- Rust compiler: Stable 1.95+.
- just (optional, command runner).
Build steps
# Clone the repository
# Compile the release CLI binary
# The optimized binary will be located at:
# target/release/hayate
Using just recipes:
✦ Acknowledgements & Special Thanks
Hayate stands on the shoulders of giants. Special thanks to the authors and maintainers of these incredible Rust crates that make this project possible:
- compio: For providing the completion-based proactor async I/O runtime (
io_uring/IOCP/kqueue). - quinn-proto: For the high-performance, protocol-correct QUIC state machine.
- rustls: For memory-safe, modern TLS 1.3 protocol support.
- ring: For robust and fast hardware-accelerated cryptographic primitives.
- dalek-cryptography (
x25519-dalek): For secure Curve25519 Diffie-Hellman exchanges. - RustCrypto (
chacha20poly1305): For pure-Rust AEAD encryption/decryption primitives. - clap: For parsing command-line parameters elegantly.
- indicatif: For the smooth terminal progress indicators.
- zstd-rs: For the lossless compression algorithms.
- rcgen: For runtime self-signed X.509 certificate generation.
✦ Changelog
See CHANGELOG.md for a list of notable changes in each version.
✦ License
MIT. See LICENSE for details.