LocalSend: two devices that have never met, locked to each other on your own Wi-Fi

1 month ago

Your video is on your phone. Your laptop is eighteen inches away, and the file goes to the internet and back. LocalSend is a free app you put on both devices. You pick the file, you pick the laptop, and the file crosses your own Wi-Fi. No account, no sign up, no company on the way.

Ask

Ask about this presentation

Answers are generated from this presentation.

Chapters

  1. 0:00LocalSend · send a file straight from your phone to the laptop across the room
  2. 0:14Your laptop is receiving the files straight from the phone on the table
  3. 0:27Each device gives itself a random name and waits to be picked
  4. 0:47A device announces itself to the whole network in nine fields
  5. 1:05The code computed from a device’s own ID card is its real name
  6. 1:42Both checks happen on the same connection, one in each direction
  7. 2:05Both versions of LocalSend point at the same engine, line for line
  8. 2:17The download page on the project’s own site has this release
  9. 2:32The file went across the room, not up to the internet and back
Show transcript

LocalSend · send a file straight from your phone to the laptop across the room

GitHub Trending · Ep 33 · Aug 13, 2026
Eighteen inches, by way of the internet.

LocalSend

send a file straight from your phone to the laptop across the room
Apache-2.0 license, free to use Android · iOS · macOS · Windows · Linux

Your video is on your phone. Your laptop is eighteen inches away, and the file goes to the internet and back. LocalSend is a free app you put on both devices. You pick the file, you pick the laptop, and the file crosses your own Wi-Fi. No account, no sign up, no company on the way.

Your laptop is receiving the files straight from the phone on the table

Your laptop is receiving the files straight from the phone on the table.

one bar for each file, and one underneath for the whole batch
the whole batch
From the project’s own screenshots

Put LocalSend on your phone and your laptop, and each turns up in the other’s list. Every file gets its own bar as it arrives, and one more bar underneath tracks the whole batch. Nothing sits between the two devices except your own Wi-Fi.

Each device gives itself a random name and waits to be picked

From the project’s own screenshots

Each device gives itself a random name and waits to be picked.

Out of the box, the traffic between them is scrambled.
A locked connection usually means a company vouched for one end of it.

Nothing here asks you to sign in, and that name is only for you to read. Out of the box, the connection between the two devices is scrambled, so anything else on the Wi-Fi hears noise. On the web, your browser trusts your bank because a company whose whole job is vouching signed off on it. Your browser was born trusting that company. On your own Wi-Fi that company is unreachable, so the two devices settle it between themselves.

A device announces itself to the whole network in nine fields

A device announces itself to the whole network in nine fields.

{
"alias": "Nice Orange",
"version": "2.2",
"deviceModel": "Samsung",
"deviceType": "mobile",
"fingerprint": "4BADDE53A7F7CDEE…",
"port": 53317,
"protocol": "https",
"download": true,
"announce": true
}
224.0.0.167 : 53317
the name you read the door to knock on the code the machines check

There is no directory here to look anyone up in, so one device shouts. Your phone throws a short note onto the network, and everything on the Wi-Fi hears it. The note says three things. What to call this device. What door to knock on to reach it. And one short code. The name is for you. The code is what the other devices go by.

The code computed from a device’s own ID card is its real name

The code computed from a device’s own ID card is its real name.

packages/core/src/crypto/cert.rs
params.distinguished_name.push( rcgen::DnType::CommonName, "LocalSend User"); let certificate = params.self_signed(&key_pair)?;

“peers identify each other purely by the certificate fingerprint, so the name carries no information.”

crate::crypto::hash::sha256(cert) .iter() .map(|byte| format!("{byte:02X}")) .collect()
4BADDE53A7F7CDEE…
The connection locks to the code of the device you picked.

That short code comes from an ID card. Every device makes its own card, right there on the device, signed by nothing. The written name on that card is the same two words on every device on earth. LocalSend User. The name was never the point. What identifies a device is a short code computed from the card. Change one dot of the card and the code comes out completely different. Your laptop turns up in the list on your phone, carrying its code. The moment you pick your laptop, your phone locks the connection to that one code. Your phone checks that code while the connection is being set up, before a single byte of your file goes out. Another machine answering at that address never hears what you were about to send.

Both checks happen on the same connection, one in each direction

Both checks happen on the same connection, one in each direction.

Your phone
Your laptop
Shouts to everything on the network at once →
← Answers directly
Must be the exact device you picked →
← Must hold the certificate for the code it claims
Checked while the connection is still being set up
What is coming →
The file →

The whole trip is five steps. Your phone shouts. Your laptop answers straight back, and that answer carries the laptop’s own code. Then the two devices check each other, and each side asks something different. Your phone asks the laptop to be the exact device you picked. Your laptop asks your phone to hold the card for the code it claims. Then your phone says what is coming. Then the file goes across the room.

Both versions of LocalSend point at the same engine, line for line

Both versions of LocalSend point at the same engine, line for line.

The app
localsend = { path = "../../core", features = ["full"] }
A plain text window
localsend = { path = "../packages/core", features = ["full"] }
One engine
the same crate and the same feature set under both, and that rewrite finished in v1.18.0, released Aug 10, 2026

The shouting, the card check, and the file moving across all run on one engine underneath. The maintainers only just finished it. So the same machinery that drives the app also drives a version in a plain text window, for a computer with no screen at all.

The download page on the project’s own site has this release

The download page on the project’s own site has this release.

Apache-2.0 license, free to use Android 5+ iOS 12+ macOS 11+ Windows 10+ Linux
Windows · portable download
v1.18.0 · released Aug 10, 2026

A lot of the usual places to get apps still have the build from February last year. Go straight to the project for this one. It is free and open, and it runs on Android, iPhone, Mac, Windows and Linux. On Windows there is no installer published yet, so you unzip the download and run it.

The file went across the room, not up to the internet and back

The file went across the room, not up to the internet and back.
github.com/localsend/localsend
new repo tomorrow

Each device worked out exactly who it was talking to, with no company in the middle. The name you read was made up. The code underneath is what the devices checked. The link is on screen, and there is a new repo here tomorrow.