Skip to content

Releases: polius/fsend

v1.7.0

25 Jun 13:20
f95ac50

Choose a tag to compare

Summary

Before a transfer starts, fsend now shows you exactly what's about to move — the file list with sizes, on both the sender and the receiver — so you can confirm you're sending (and receiving) the right thing.

See what you're transferring

Run fsend on a folder and you get a preview before anything leaves your machine:

  Sending proj/  ·  4 files  ·  1.3 MB
      921.6 KB   video.mp4
      307.2 KB   audio.m4a
       51.2 KB   notes/outline.md
          11 B   README

The receiver sees the same list before accepting. Largest files come first (trimmed to the top 10, with a … and N more line), and the sizes always add up to the total in the header.

Machine-readable output for scripts

When you're driving fsend from a script rather than watching the terminal, two new flags hand you the file list as plain CSV — one for each side of a transfer:

  • On the sending side, --preview lists every file fsend would send — path,size — then exits. No code, no transfer, nothing leaves your machine:
    fsend --preview proj/
    
    It prints to standard output, so redirect it to a file when you want to keep it, e.g. fsend --preview proj/ > files.csv.
  • On the receiving side, --manifest writes a record after the transfer finishes: each received file as path,size,status, where status is new, identical, overwritten, kept, or resumed:
    fsend abc-defg-jkm --manifest record.csv
    

Symlinks are followed

fsend now sends what a symlink points to, not the link itself, so the receiver ends up with a real file instead of a link that dangles on their machine. In the preview the file shows where it came from, like latest (→ video.mp4).

A link whose target is missing, unreadable, or loops back on itself stops the send with a clear error (E036) rather than being silently dropped — fix the link or skip it with --exclude.

Fixes

  • Large transfers no longer drop. A packet-demultiplexing collision between STUN and QUIC could tear down big transfers mid-flight over the internet path.
  • Share codes shrug off stray whitespace and capitalization. A code pasted with a trailing space or newline — a Windows CRLF, or one a chat app auto-capitalized — is now accepted instead of failing with a confusing "no such file." Only the code argument is normalized; filenames are left exactly as typed.

Changelog

How to update

Note

To update, run fsend --update, or re-run the command from the Install section.

v1.6.0

22 Jun 15:39
9849c22

Choose a tag to compare

Summary

Re-sending is now incremental: fsend transfers only the files the receiver doesn't already have, instead of sending the whole set every time.

How it works

Before transferring, fsend checks each file against the receiver and sends only the ones that aren't already there — anything it already has is left as is.

  • A file that exists but is different is never replaced unless you add --overwrite, so you can't accidentally clobber someone's local edits.
  • fsend never deletes anything on the receiver.

For example, say you send a folder of 500 files:

fsend ./project

The first run transfers all 500. If you add a couple of files and run the same command again, fsend sends just those new files and skips the other 500.

New options

Option What it does
--dry-run Show what would be sent (new / unchanged / different) without transferring anything.
--checksum Use this when timestamps can't be trusted (files were copied, restored from backup, or regenerated). It compares actual file contents instead of size and date — slower, but accurate. (Same idea as rsync's -c.)

Reliability & security

This release also lands a round of hardening:

  • Crash-safe writes. Received files are flushed to disk before fsend marks them complete, so a crash or power loss mid-transfer can't leave a file that looks finished but is silently corrupt.
  • Signed installs and updates. The installer and fsend --update now verify the release's cryptographic signature (cosign), not just its checksum — a tampered download is rejected, not only a corrupted one.
  • Up-to-date runtime. Built on the latest Go patch release, clearing every known vulnerability in the underlying libraries, with an automated check to keep it that way.
  • Steadier connections. Retries now spread out to avoid hammering a busy server, the local-network fast path shrugs off a misbehaving device on the same Wi-Fi, pressing Ctrl-C during a transfer stops promptly instead of hanging, and fsend --uninstall returns a proper error code when it can't remove the binary.
  • Sturdier self-hosted server. If you run your own pairing/relay server, it now shuts down gracefully — draining in-flight relayed transfers before stopping, so upgrades don't cut active transfers — recovers from a malformed packet instead of crashing, and reports an unhealthy status when its relay has failed so your orchestrator can restart it.
  • Hardened against hostile peers. The protocol parsers are now fuzz-tested and the work a peer can request is bounded, so a malicious party on the other end can't exhaust memory or crash your transfer. A related fix: files and folders whose names start with two dots (like the ..data directories Kubernetes creates) now transfer correctly instead of being wrongly rejected.

Compatibility

Important

This version isn't compatible with older versions of fsend, so the sender and the receiver both need to be on v1.6.0 or newer. Update with fsend --update.

Changelog

v1.5.0

12 Jun 13:53
d07107f

Choose a tag to compare

Changelog

v1.4.0

12 Jun 08:32
36cfeca

Choose a tag to compare

Changelog

v1.3.0

12 Jun 00:18
3441816

Choose a tag to compare

Changelog

  • 3441816: feat(ice): serve STUN from the relay socket so NATed peers connect direct (#54) (@polius)

v1.2.0

11 Jun 23:00
590e163

Choose a tag to compare

Changelog

  • 590e163: feat(install): add native PowerShell installer for Windows (#53) (@polius)

v1.1.0

11 Jun 21:35
a4dda70

Choose a tag to compare

Changelog

v1.0.0

11 Jun 20:41
cc1026a

Choose a tag to compare

Send a file straight from one machine to another with a single command — no accounts, no uploads to the cloud, no third party ever touching your data.

$ fsend report.pdf                 # home Wi-Fi
Share this code:  abc-defg-jkm

$ fsend abc-defg-jkm               # café Wi-Fi, two continents away
✓ Saved report.pdf to ~/Downloads  ·  2.4 MB  ·  1.3s  ·  Direct over the internet

One code. Bytes flow straight between the two machines at your own speed — encrypted end-to-end the whole way.

Install

curl -fsSL https://getfsend.alzina.dev | sh

Linux · macOS · FreeBSD · Windows — x86 and ARM. A single static binary, nothing else to set up.

About

  • 🔗 Truly peer-to-peer — fsend races a LAN path, a direct internet path, and a relay, and the bytes take the best one. The relay is a last resort and never sees your file.
  • 🔒 End-to-end encrypted — TLS 1.3 between peers, authenticated by your share code (PAKE). Hardened against tomorrow's quantum computers with X25519 + ML-KEM-768.
  • 📦 Send anything — files, whole folders, several paths at once, a piped stream, or a line of text. Drops mid-transfer? Rerun the command and it resumes.
  • 🔑 Optional password — gate any transfer with --pass.
  • 🪶 Lives nowhere but the two ends — no servers storing files, no metadata trails. Self-host the pairing server in minutes if you want full control.

Full usage, architecture, and self-hosting docs live in the README. Questions or bugs? Open an issue. MIT licensed.