vX.Y.Z releases floe.one, the floe CLI, and the server you can run yourself. desktop-vX.Y.Z releases Floe Desktop for Windows. The two never need to match, and no release so far has changed the transfer protocol, so every version of Floe sends to and receives from every other one.
Each entry lists the parts it changed. Filter on the right to see only the ones you use.
A send over a slow or lossy connection no longer fails in its last moments
- After the last file went out, Floe gave the other side 30 seconds to confirm delivery. Up to 8 MB can still be on its way at that point, so on a slow or lossy connection a send could stop at 94 to 99 percent with a delivery timeout, and the person receiving lost the file. Floe now keeps waiting as long as that remaining data is still moving, and stops only after a full minute in which nothing more gets through.
- A connection that has really stopped is still caught: when nothing moves for a minute, or the other side disconnects, the send ends as before.
- The wire protocol is unchanged, so 0.2.12 transfers with older CLI, desktop, and browser peers in both directions.
floe send no longer gives up at 94 to 99 percent on a slow or lossy connection- After the last file,
floe sendwaited a fixed 30 seconds for the receiver to confirm delivery. Up to 8 MB can still be queued at that point, so a transfer whose final stretch ran below about 1 Mbps failed withtimed out waiting for delivery confirmation from peer, and the receiver deleted the incomplete file. The sender now keeps waiting while that data is still draining, and gives up only after a full minute with no progress, the same rule the rest of a transfer already follows. - A receiver that stops responding is now reported after 60 seconds of no progress instead of a fixed 30 seconds.
- Self-hosting: the published images are rebuilt as
1.10.11. They include internal cleanups since1.10.10and no configuration change. If you pinnedFLOE_IMAGE_TAG=1.10.10, move to1.10.11. - The wire protocol is unchanged, so this still transfers with older CLI, desktop, and browser peers in both directions.
Six ways to stop a signaling server with one unauthenticated request are closed
- Six different requests could end the signaling server process. Rooms are held in memory, so each one also dropped every transfer that was in progress at the time. None of them needed a room, a share code, or any credential, and the smallest was four bytes.
- Three arrived during the WebSocket handshake: a request path that Node accepts but the URL parser rejects, a client disconnecting at one precise moment, and a path spelled so that both the browser route and the command-line route claimed it at once.
- Three arrived over an established connection: a message consisting of the single word
null, a deeply nested signal, and a malformed frame on a connection that had just been rate-limited. - The server now survives an unexpected error rather than exiting, so a fault nobody anticipated costs one connection instead of every transfer on the server. All six are fixed where they happen, and the test suite fails if any of them reaches that safety net instead.
- Self-hosting: the published images are rebuilt as
1.10.10. This is a security fix. If you run your own server, update; if you pinnedFLOE_IMAGE_TAG=1.10.9, move to1.10.10. floe.one was updated separately and is already running it. - The
floecommand-line tool is unchanged in this release, and so is the wire protocol, so this still transfers with older CLI, desktop, and browser peers in both directions.
Hide my IP now says when a server cannot do it, instead of failing half a minute later with connection advice
- Hide my IP address needs the server to offer a relay, and against a self-hosted server without one the transfer used to run for about thirty seconds and then fail with “A connection could not be established. Check that both devices are online and try again.” Both devices were online. The transfer now stops immediately and names the setting, before a share code is even created, so nobody is handed a code that could never have connected.
- The Test button in Settings reports it too. A server with no relay still passes, because it works for any transfer that finds a direct path, and the result now reads Connected. This server has no TURN relay, so Hide my IP will not work. Test previously answered a bare Connected. for that server, which is what let the problem surface much later somewhere else.
- The two causes are kept apart. If Floe cannot read the server’s connection details at all, because the address is wrong, a reverse proxy is not forwarding
/api/, or the request was rate-limited, it says that rather than claiming the server has no relay. It never saw the server’s answer, so it does not guess at one. - Test also no longer accepts a server that answers with connection details containing nothing to connect with.
- The wire protocol is unchanged, so 0.2.11 transfers with older CLI, desktop, and browser peers in both directions.
--relay-only says when a server has no relay, instead of failing half a minute later with a generic timeoutfloe send --relay-onlyandfloe receive --relay-onlyagainst a server that offers no TURN relay used to wait about thirty seconds and end withtimed out establishing a connection, the same line--no-relayproduces for the opposite reason, naming neither the flag nor the server. Both now stop before the transfer starts with--relay-only needs a TURN relay and <server> offers none, and a sender stops before registering a code that could never have connected.- A second wording covers the case where the connection details could not be read at all, from a wrong
--server, a reverse proxy not forwarding/api/, or the endpoint’s own rate limit. Floe falls back to public STUN there and cannot see what the server offers, so it says so rather than blaming the server’s configuration. - Web app: when two peers cannot agree on a protocol version, the explanation each side puts on the wire is now written for whoever reads it, so a CLI or desktop peer that displays it word for word names the correct side and is not told to refresh a page. A browser that is itself the older side now reads its own remedy rather than the neutral wording. No release can trigger this today, since every peer speaks the same protocol.
- Web app: the protocol numbers inside that message are treated as text chosen by the other side, like every other value that arrives from a peer, so a hostile one can no longer reorder the error on screen or run past the length limit the rest of the message respects.
- Self-hosting: the published images are rebuilt as
1.10.9. If you pinnedFLOE_IMAGE_TAG=1.10.8, move to1.10.9. - The wire protocol is unchanged, so this still transfers with older CLI, desktop, and browser peers in both directions.
A small JSON file arrives intact, a file that changes while it is being sent is caught before it is sent wrong, and a transfer that is stopped on purpose says why
- A file whose entire content is one of Floe’s own control messages, such as the 14 bytes
{"type":"end"}, was read as that message and never written. A receiver now decides what an arriving frame is from how it was sent rather than from what is inside it, so a small.jsonfile arrives byte for byte. Sending one through Send text was the shortest way to hit this. - Sending a file that is still being written to now stops at the size Floe announced. A file that grew between being measured and being read, an active log or a download still running, put more bytes on the wire than promised, and the receiving end abandoned the whole batch with a message that named nothing anyone could act on. Growing and shrinking are both caught on the sending side now, and the message names the file rather than the network.
- A transfer stopped on purpose now says why. Blocking on the 2 GB relay cap, and refusing a file that did not arrive whole, both used to reach the other end as a bare disconnection; a sender with more files to send waited out the full two-minute acknowledgement deadline and then blamed a timeout.
- Receiving many files whose names collide once Windows-reserved characters are replaced is no longer slow. A thousand such files took about 42 seconds of pure filename searching before any of them were saved.
- The wire protocol is unchanged, so 0.2.10 transfers with older CLI, desktop, and browser peers in both directions.
A small JSON file arrives intact, a file that changes while it is being sent is caught before it is sent wrong, and a transfer that is stopped on purpose says why
- A file whose entire content is one of Floe’s own control messages, such as the 14 bytes
{"type":"end"}, was read as that message and never written. Every receiver now decides what an arriving frame is from how it was sent rather than from what is inside it, so a small.jsonfile arrives byte for byte. floe sendstops at the size it announced. A file that grew between being measured and being read, an active log or a download still running, put more bytes on the wire than promised, and the receiving end abandoned the whole batch withsender exceeded the announced size, which named nothing either person could act on. Growing and shrinking are both caught on the sending side now, and the message names the file’s own change.- A transfer stopped on purpose says why. Blocking on the 2 GB relay cap, and refusing a file that did not arrive whole, both used to reach the other end as a bare disconnection. A sender with more files to send waited out the full two-minute acknowledgement deadline and then blamed a timeout.
floe receiveno longer slows down on many files whose names collide once Windows-reserved characters are replaced. Seven characters that Windows refuses in a name all become_, so names that were distinct on the sending machine land on the same one; a thousand of them took about 42 seconds of pure filename searching before any were saved. What happens to those names is now written down in Known limitations.- Web app: a receiver whose sender walked away kept showing a connected badge and its last status line. It now says the transfer ended.
- Web app: a receiver used to answer every connection problem with Ask the sender to enable Network Relay, including when the sender had deliberately stopped and when the relay was already on and its 2 GB cap was the real problem. It now says what actually happened.
- Web app: a control message larger than the 1000-byte limit was written into the file being received instead of being refused. A deep enough folder path can produce one.
- Self-hosting: the published images are rebuilt as
1.10.8. If you pinnedFLOE_IMAGE_TAG=1.10.7, move to1.10.8. - The wire protocol is unchanged, so this still transfers with older CLI, desktop, and browser peers in both directions.
Transfer speed and time remaining are readable again, and a finished transfer stops claiming it is still using the relay
- Speeds under 1 MB/s read
0 KB/swhile bytes were moving. The reading now carries one decimal, the same as the web app and the CLI, so a slow transfer reads0.5 KB/s. - Time remaining had no hours. A long transfer read
166m 40swhere the web app and the CLI both said2h 46m. It now rolls over into hours, and it can no longer print1m 60sat the moment a minute turns over. - After a relayed transfer finished, the idle badge still showed the amber relay dot beside Ready. The route is cleared whenever a transfer ends, whether it finished, failed, or was cancelled.
- A History file that could not be read was replaced with an empty one on the next launch, so rows that might have been recovered by hand were destroyed before anyone could look. A store that fails to load is now left untouched.
- A failed settings write, which happens when the config folder cannot be written, raised an unhandled error during startup. It is now handled.
- Codes are matched without regard to capitalization, so
Olive-Tiger-Castle, which is what a phone keyboard produces, resolves the same asolive-tiger-castle. - Asking the signaling server for relay credentials or for a code now gives up after 30 seconds instead of waiting indefinitely, so a server that accepts the connection and then goes quiet no longer leaves the app waiting with nothing to show.
- A repeated message from the signaling server can no longer stall a connection that is being set up.
- Every transfer now releases the two background tasks it starts. Floe Desktop builds a fresh connection for each transfer, so these accumulated for as long as the app stayed open.
- The wire protocol is unchanged, so 0.2.9 transfers with older CLI, desktop, and browser peers in both directions.
Room codes work whatever case you type them in, and the network calls that could wait forever now give up
- A code is matched without regard to capitalization.
floe receive Olive-Tiger-Castle, which is what a phone keyboard produces, now resolves the same asolive-tiger-castleinstead of failing withcode not found or expired. Room links are unchanged: the room id in a link is still case-sensitive. floe sendandfloe receivegive the server 20 seconds to assign a role, then fail withtimed out waiting for the server to assign a role. A server that accepted the connection and then went quiet used to hang the command indefinitely. If the other side leaves during that window, the message says so instead.- Fetching relay credentials and registering or resolving a code now give up after 30 seconds. Both used to have no deadline at all.
- When the signaling server refuses a relay-credentials request,
floesays so and continues without the relay, rather than falling back in silence:Warning: signaling server returned 429 for TURN credentials. Using STUN only. - A repeated message from the signaling server can no longer stall a connection that is being set up. This is on the path every transfer takes first.
- Every transfer releases the two background tasks it starts instead of leaving them running.
floe updatecould pin its own check off permanently if the cache carried a timestamp in the future. It now treats that as expired.- Web app: files dropped in the moment between clicking Create secure link and the link appearing were counted, shown with a green check, and never sent. The file set is now sealed the moment you click, and the card shows that the link is being created rather than going blank for up to three seconds.
- Web app: a receive that ended partway through a batch reported Transfer complete. It now reads Sender disconnected. 1 of 3 files received.
- Web app: a sender whose receiver closed the tab at the wrong moment could wait forever instead of failing, and the acknowledgement timer was never cleared once an acknowledgement arrived.
- Web app: sizes are formatted safely at both ends of the range.
formatBytesreturnedNaN undefinedfor a negative number and1 undefinedpast terabytes. Time remaining could read1m 60s. - Web app: a
.gofile gets the code icon, a file with no extension at all no longer borrows one, and the relay cap beside the file count reads2 GB, matching every other place the number appears. - Web app: when a peer is too old to talk to, the message no longer tells a browser user to run a command-line tool they may not have.
- Self-hosting: the published images are rebuilt as
1.10.7. If you pinnedFLOE_IMAGE_TAG=1.10.6, move to1.10.7. - The wire protocol is unchanged, so this still transfers with older CLI, desktop, and browser peers in both directions.
The CLI can hide your IP address by forcing the relay, and says which route each transfer took
- A new
--relay-onlyflag onfloe sendandfloe receiveroutes the whole transfer through the TURN relay and never tries a direct path, so the other side sees the relay’s address instead of yours. It is the command-line twin of Floe Desktop’s Hide my IP address setting, applies to your side only, and can be kept on withFLOE_RELAY_ONLY=1. While it is on, the 2 GB relay cap applies to every transfer. It cannot be combined with--no-relay, and a typed--no-relayoverrides the variable for that one command. - Once the connection is up, the
Connectedline names the route:Connected (direct)when the two devices talk to each other,Connected (relay)when the transfer runs through the TURN relay. If the route cannot be read, the line staysConnectedand the transfer proceeds as before. A script that matched that line exactly should match on theConnectedprefix instead. - Against a server that offers no TURN relay,
--relay-onlyhas nowhere to go and fails after about 30 seconds withtimed out establishing a connection, the same generic timeout--no-relayproduces when no direct path exists. - Web app: the privacy policy’s opt-out instructions now name Floe Desktop’s Settings switch alongside the browser checkbox and the CLI’s
--no-report. Only the wording was incomplete; all three opt-outs already worked. - Self-hosting:
GET /api/confignow returns acommitfield next tosocketUrl, naming the source revision the client was deployed from, so anyone can check which build an instance is running. SetSOURCE_COMMITin the client container’s environment to fill it in; it reportsnullwhen unset. Compose does not pass the variable through, so add it to the client service yourself if you want it served. - Self-hosting: the published images are rebuilt as
1.10.6. No Floe code changed in either one; the client image picks up Next.js 16.3.3 and the server image picks upws8.21.3. Next.js 16.3.3 is a security release for two advisories rated critical, and neither one reaches Floe as it ships: one needs a Windows host and both images are Linux, and the other needs an AVIF image through the optimizer, which the client does not enable. So pull when convenient rather than urgently. If you pinnedFLOE_IMAGE_TAG=1.10.5, move to1.10.6. - The wire protocol is unchanged, so this still transfers with older CLI, desktop, and browser peers in both directions.
A file name chosen by the other side can no longer disguise its extension in the incoming preview, and an impossible file size no longer closes the app
- The incoming preview shows a cleaned name: control characters and text-direction marks become underscores, and a name longer than 200 characters is shortened with its extension kept. The name saved on disk is unchanged, and the progress line and History show the name as it was saved.
- A sender that announced a negative or impossibly large file size ended the whole app before the preview appeared. Sizes and file counts are now checked as the announcement arrives, and an announcement that cannot be right ends the transfer with an error in the status line instead.
- A file that keeps arriving past the size the sender announced is stopped at the first extra byte and the partial file is removed.
- The status line shows cleaned messages from the shared engine, including the version string and rejection reason a peer sends back.
- A control message longer than 1000 bytes ends the transfer with an error instead of being parsed, and a receiver that asks to resume from a position outside the file is refused.
- The fix is on the receiving side, so a transfer is protected once the receiving end runs Floe Desktop 0.2.8 or
floe1.10.5. The wire protocol is unchanged, so 0.2.8 transfers with older CLI, desktop, and browser peers in both directions.
A file name or version string chosen by the other side can no longer rewrite the terminal, disguise its extension in the accept prompt, or crash the receiver
floe receiveshowed the sender’s file name exactly as sent in the Incoming box and theAccept? [Y/n]prompt. The name was only cleaned later, when the file was written, so a name containing terminal control codes could erase or redraw the prompt, and a text-direction mark could makephotofollowed by a reversedexe.pngread as an image while the file was a program. The Incoming box, the accept prompt, the peer version note, progress reporting, and every error message now show a cleaned name: control characters and text-direction marks become underscores, and names longer than 200 characters are shortened with the extension kept. The name saved on disk is unchanged.- A sender that announced a negative or impossibly large file size made the receiver crash before the prompt appeared. Sizes and file counts are now checked as the announcement arrives, an announcement that cannot be right ends the transfer with an error instead, and
floe sendshows that reason rather than only reporting a closed connection. - A file that keeps arriving past the size the sender announced is stopped at the first extra byte and the partial file is removed, instead of the overrun being caught only when the file ends.
- A receiver that asks to resume from a position outside the file is refused by
floe send, instead of the transfer hanging or sending nothing. floe receivenow ends the transfer with an error when a control message is longer than 1000 bytes, instead of parsing it, matching the limit the web app has always enforced.floe senddrops such a frame and keeps waiting for a valid one.floe sendcleans and shortens the version string and the rejection reason a receiver sends back before printing them.- Web app: the error shown when a file arrives incomplete, and the message shown when the other side rejects a transfer, have control characters and text-direction marks removed and are shortened before they appear on the page. The web app also refuses a resume position outside the file instead of sending nothing forever.
- Self-hosting: the published images are rebuilt as
1.10.5. Nothing in the server changed, so pull when convenient. If you pinnedFLOE_IMAGE_TAG=1.10.4, move to1.10.5. - The fix is on the receiving side. A transfer is protected once the receiving end is running
floe1.10.5 or Floe Desktop 0.2.8; sending from an updated build to a peer that has not updated is unchanged. The wire protocol is unchanged, so v1.10.5 still speaks to older CLI, desktop, and browser peers in both directions.
A killed transfer never leaves a half-written file looking finished, closing mid-transfer asks first, and Send with Floe keeps every file
- A received file is now written under a temporary name ending in
.partand takes its real name only once every byte has arrived. Before this, closing the window, ending the app from Task Manager, or losing power partway through left the unfinished file in your folder under its final name, looking complete. Now the worst that can remain is a.partfile, which is safe to delete. - Closing the window during a transfer asks first. A new prompt offers Keep going or Close anyway, so one stray click on the close button no longer cuts a transfer off for both sides with nothing on screen.
- Send with Floe on several files at once now sends all of them. Windows starts Floe once for each file you select, and files that arrived before the window finished loading used to be silently dropped, so a five-file selection could send only one. Every selected file now lands in the same window.
- The file name that is shown and the one that is saved stay in step even when a name collision is only discovered as the file finishes, so Open and Show in folder always act on the file you actually received.
- No transfer-protocol change, so Floe Desktop 0.2.7 transfers with browser and CLI peers in every direction.
Received files are written under a temporary name and only renamed when complete, so a killed transfer never leaves one looking finished
floe receivenow writes each file under a temporary name ending in.partand renames it to its final name only after every byte has arrived and been verified. A transfer killed outright, or a machine that loses power partway through, can no longer leave a half-written file under a finished-looking name; the worst that remains is a.partfile, safe to delete. On Windows the final rename is atomic; on macOS and Linux a crash at the exact instant of completion can leave an empty placeholder beside the intact.part.Ctrl+Cremoves the in-flight.partfile on the way out, so a canceled receive leaves the output directory clean.- The fix is on the receiving side. A transfer is protected once the receiving end is running
floe1.10.4 or Floe Desktop 0.2.7; sending from an updated build to a peer that has not updated is unchanged. - Self-hosting: the published images are rebuilt as
1.10.4. This release only touches the receive path the CLI and desktop app share, so there is nothing you need to do; pull when convenient. If you pinnedFLOE_IMAGE_TAG=1.10.3, move to1.10.4. - The wire protocol is unchanged, so v1.10.4 still speaks to older CLI and browser peers in both directions.
Files whose names Windows cannot hold now arrive intact instead of arriving empty
- A file sent from a Mac or a Linux machine can carry a name Windows has no way to store. A timestamp like
backup:2026-08-19.logis the everyday case, because Windows gives the colon a special meaning. Floe used to write that file, report success, and leave you an empty file calledbackup, with the contents routed somewhere you would never find them. Names likewhat?.txtwere worse still: the file could not be created at all, and the error ended the rest of the batch, so files queued behind it never arrived. - Incoming names are now adjusted before the file is written. The characters
< > : " | ? *become underscores, trailing dots and spaces are removed, and a name that is a reserved device name such asNULgets an underscore in front. The progress line and Show in folder both use the adjusted name, and two files that end up with the same adjusted name are numbered the way colliding names always have been. - A file named with a trailing space used to lose its mark of the web, the tag that makes Windows treat a received file as downloaded from the internet. The tag attached to the wrong name and the saved file kept none, so SmartScreen and Office Protected View stayed out of the way on a file a stranger sent you. Received files are now tagged correctly whatever they are called.
- Control characters and text-direction marks are removed from incoming names on every platform. A text-direction mark can make
photofollowed by a reversedexe.pngread as an image in the file list while the file on disk is a program. - Folder sends keep their structure. Each part of the path is adjusted on its own, so a folder that needed adjusting stays a folder.
- No transfer-protocol change, so Floe Desktop 0.2.6 transfers with browser and CLI peers in every direction.
Received files that a system cannot store, and browser downloads that were never complete, no longer pass as finished
floe receiveadjusts an incoming file name that the receiving system cannot represent, instead of writing it and reporting success. On Windows a name likebackup:2026-08-19.logused to leave an empty file calledbackup, a file calledNULleft nothing at all, and a name containing?could not be created and ended the rest of the batch. macOS and Linux keep names exactly as sent, since all of those are valid there.- On Windows, a received file named with a trailing space used to lose its mark of the web, so SmartScreen and Office Protected View did not apply to it. That tag now attaches correctly whatever the file is called.
- Control characters and text-direction marks are removed from incoming names on every platform, and the receiver refuses to write onto a device rather than discarding the contents silently.
- The fix is on the receiving side. A transfer is protected once the receiving end is running
floe1.10.3 or Floe Desktop 0.2.6; sending from an updated build to a peer that has not updated is unchanged. Both surfaces ship the fix in this pair of releases. - Web app: a file that arrived incomplete is no longer offered as a finished download. The browser labeled each file with however many bytes turned up rather than the number the sender announced, so the two could never disagree and a file cut short still showed a checkmark and a working download button. It is now checked against the announced size and refused if it does not match, and a short count is no longer added to the public transfer counter.
- Web app: sending a file that becomes unreadable partway through, because it was moved, renamed, or sat on a drive or cloud folder that went away, now reports the failure instead of telling both sides the file finished.
- Web app: file names chosen by the sender are cleaned before they are used to name a download or an entry in a ZIP, so a name cannot describe a path or quietly drop a file from the archive.
- Web app: a transfer blocked by the 2 GB relay cap now closes the connection and explains itself, instead of leaving the other side waiting with nothing on screen.
- Self-hosting: the published images are rebuilt as
1.10.3and carry the web app changes above. To pick them up:docker compose pullthendocker compose up -d; if you pinnedFLOE_IMAGE_TAG=1.10.2, move to1.10.3. - The wire protocol is unchanged, so v1.10.3 still speaks to older CLI and browser peers in both directions.
Empty a staged selection in one click, and a fix for transfers that connected but never started
- A Clear button now sits beside Send on the send card. It empties whatever the tab you are on is holding, the file list on Files or the box on Text, and leaves your settings, the Receive tab, your history and the files themselves alone. It appears only when there is something to clear, and steps aside for Cancel while a send is running.
- Clear does not ask first. It offers Undo instead, in a bar at the bottom of the window that puts back exactly what you had staged, whitespace and all. The bar shows for about ten seconds, longer while you point at it or reach it with the keyboard.
- The undo outlasts the bar.
CtrlZstill takes it once the bar has gone, and it stands until you put something new on that same tab, clear something else, or start over. Switching tabs, opening Settings or checking History only puts the bar away, and it comes back when you do. Like the app’s other shortcuts,CtrlZwaits while the cursor is in a text box. - Start over now asks before discarding a note you have cleared, the same way it already asks about a note you typed but never sent.
- Fixed transfers that connected and then moved nothing: both ends showed a healthy connection, then sat silent until a timeout blamed the other side. The very first message of a transfer could be dropped before the receiving app was listening for it. The odds turn on the round trip between the two peers, so it was rare across a network and common between two Floe apps on one machine. The fix is on the receiving side, so a transfer is protected once the receiving end is running Floe Desktop 0.2.5 or
floe1.10.2. Sending from this build to a peer that has not updated is unchanged. - Every row in History is now a single button that opens and closes the row, with one chevron in the same place on every row. The opened row carries the file names, and for a received transfer where it was saved plus a Show in folder action; every row carries Remove. Finishing a transfer no longer shifts which row is open, because a new entry goes on top and the open row used to be tracked by position.
- The dashed borders on the drop area read as soft white now and brighten when you point at them. The blue is kept for the highlight that appears while you are actually dragging files over the window.
- Turning off animations in Windows now stops the app’s own animations. The setting was being ignored, so the update notice, the Settings panel, tooltips, the connection dot and the new undo bar all moved anyway.
- The focus outline on buttons is brighter, so it is easier to see where the keyboard is.
- No transfer-protocol change, so Floe Desktop 0.2.5 transfers with browser and CLI peers in every direction.
Fixed transfers that connected and then moved nothing
- A transfer could reach the point where both ends reported a healthy connection and then never start, ending 30 seconds later with
connected, but no data arrived from the senderon one side and a message blaming the receiver on the other. The very first message of a transfer could be dropped before the receiving side was listening for it, and because the network layer had already accepted that message, nothing ever resent it. - The window is microseconds wide and closes as the round trip between peers grows, so it was rare between two machines and common between two Floe processes on one machine. It has been there since the first release.
- The fix is on the receiving side. A transfer is protected once the receiving end is running
floe1.10.2 or Floe Desktop 0.2.5; sending from an updated build to a peer that has not updated is unchanged. Both surfaces ship the fix in this pair of releases. - Self-hosting: the published images are rebuilt as
1.10.2with nothing of their own changed, since this release only touches the transfer engine the CLI and the desktop app share. There is nothing you need to do; pull when convenient. - The wire protocol is unchanged, so v1.10.2 still speaks to older CLI and browser peers in both directions. That is a statement about compatibility, not about the bug above, which is fixed for whichever end is running the new build.
A cleaner update notice, and the main screen says precisely what happens to your files
- The update notice is redrawn as a slim one-row frosted bar with a whisper of ice in its border. What it does is unchanged.
- The main screen’s subline now promises “no uploads” instead of “no middleman”. A relayed transfer does pass through a relay, so the old word claimed too much; nothing is uploaded on any path.
- No transfer-protocol change, so Floe Desktop 0.2.4 transfers with browser and CLI peers in every direction.
Failed or stalled receives clean up their partial file
floe receiveno longer leaves a half-written file behind under its final name when a transfer fails or stalls. The partial is deleted, files that completed earlier in the batch are kept, and a retried transfer gets its original name back instead of a numbered one.- The protocol-incompatibility message the CLI sends across the wire is now worded from the reader’s perspective, so older versions that display it word-for-word name the correct side. No release can trigger this today (every peer speaks the same protocol).
- Web app: the navbar now adapts to window width in three steps instead of two, and the Download link is visible at every size; it previously appeared only on wider windows, so the header offered no way to reach the desktop app’s download page on a phone.
- Web app: floe.one and the docs now share the same four-column footer (Product, Documentation, Project, Legal), and it appears on every page of the site rather than only the homepage and the download page.
- Web app: fixed the docs pages showing outdated content that a reload could not refresh; an offline cache was keeping old copies forever, and they now clear automatically on your next visit.
- Self-hosting: the published images carry every web-app change above plus updated dependencies (Next.js 16.3.0 and
ws8.21.2). To pick them up:docker compose pullthendocker compose up -d; if you pinnedFLOE_IMAGE_TAG=1.10.0, move to1.10.1. - No transfer-protocol change, so v1.10.1 interoperates with older CLI and browser peers in every direction.
Failed transfers clean up after themselves and speak plainly, and Start over stops losing notes
- A receive that fails or is cancelled partway no longer leaves a half-written file behind under its final name. The partial is deleted, files that completed earlier in the batch are kept, and a retried transfer gets its original name back instead of a numbered one.
- The Receive card now shows what is incoming (the file name and size, or the file count and total) the moment the sender is known, before the first byte arrives.
- A failed receive now raises a Windows notification like a failed send always did, and cancelling a transfer no longer raises a false “send failed” one.
- Transfer errors are now written for people (“The connection was lost before the transfer finished. Start it again.”) instead of surfacing the engine’s internal wording. Genuinely unknown failures still show the raw text so bug reports stay useful.
- Cancelling a transfer and immediately starting another no longer lets the dead attempt interfere: its late events are ignored, it can no longer release the keep-awake lock the new transfer holds, and Cancel always reaches the transfer that is actually running.
- The app now checks GitHub once a day for a newer desktop release and shows a small dismissible notice when one exists, with a matching row in Settings under About. GitHub-channel builds only: the Microsoft Store build never checks, because the Store updates it itself. Nothing downloads or installs by itself. A new Check for updates switch in Settings under Privacy turns the check off, and off means no request is made at all.
- Protocol-incompatibility messages now name the remedy for the surface you are on: the desktop app points at the Microsoft Store or floe.one/download instead of the CLI’s
floe update, and the message sent across the wire is worded from the reader’s perspective, so older versions that display it word-for-word name the correct side. No release can trigger this today (every peer speaks the same protocol); it prepares the messaging for any future wire change. Contributed by the project’s first external code contributor. - Fixed Start over still discarding a typed note without asking, in the two cases the 0.2.2 fix missed. Typing a new note after a send completed, and typing a note then switching to Files and sending those instead, both left text in the box that had never gone anywhere, and both were cleared with no prompt. Floe now compares the box against what the last completed send actually put on the wire, so a note only counts as sent while it is still exactly the note that went out. Tidying up after a send with the sent note still in the box is unchanged and still silent, as is starting over while a connection is being set up.
- Fixed a failed transfer leaving its progress bar frozen on screen underneath the error, on both the sending and the receiving side.
- Fixed Start over offering to cancel a transfer that had already failed. The stale progress bar above was also what the confirmation read, so after a failure it warned about cancelling a transfer that was already over, and that warning hid the one about the unsent note behind it.
- No transfer-protocol change, so Floe Desktop 0.2.3 transfers with browser and CLI peers in every direction.
Stalled transfers now fail with a reason, and received files are never overwritten
floe sendandfloe receiveno longer wait forever when a connection half-forms. Waiting for the peer’s offer or answer is capped at 30 seconds, establishing the connection at 30 more, with a 10 second grace for the data channel once the peers are otherwise connected. Each says which stage gave up:timed out waiting for the peer's offer,timed out establishing a connection,connected but the data channel did not open. None of this limits how long a sender waits for a receiver to arrive, which is still unbounded, so sharing a code and walking away works exactly as before.floe receiveno longer overwrites an existing file that has the same name as an incoming one. The new file is saved with a numbered suffix before the extension (report.pdf, thenreport (1).pdf), the same way browsers de-duplicate downloads. The progress line shows the name actually written.- On Windows, received files are now tagged with the mark of the web (a
Zone.Identifierstream), so SmartScreen and Office Protected View treat them like browser downloads when opened. FLOE_SERVERandFLOE_WEBset the server and web addresses for every command, so a self-hosted setup no longer repeats--serveron each one. An explicit flag still wins over the environment.- A trailing slash on a self-hosted server address no longer kills the transfer.
--server https://example.com/builthttps://example.com//api/code, which answers 404, and that 404 was swallowed into a silent fall back to public STUN, so a relayed transfer failed with nothing to explain it. Surrounding whitespace and any run of trailing slashes are now trimmed. - A receive code that has already been used says
this code is no longer active; ask for a new one. It used to report an unexpected role, which described the internals rather than the situation. - Web app: session replay is gone from floe.one. Recordings masked all text and media, so file names and contents were never captured, but a recording reported the page address, and a receiver’s address carries the room link. That link is the only thing protecting a transfer. It is now stripped from error reports and breadcrumbs too.
- Web app: the analytics script no longer receives the room link either. It reported the full address on page load, so a receiver opening a share link handed the room secret to a third party. It now sees the path alone.
- Web app: floe.one sends a content security policy that refuses to be framed, alongside
X-Content-Type-Options,Referrer-Policy,Permissions-Policyand HSTS. - Self-hosting: the published images run Node 24, the Active LTS, again. A dependency update had moved them to Node 25, which reached end of life on 2026-06-01 and will receive no further security patches.
- Self-hosting: the signaling server no longer returns a stack trace when a request fails. It answers with a plain JSON error instead.
- Self-hosting: the room-code word list is deduplicated and extended to 288 unique words. Thirteen words appeared twice, which made some phrases likelier than others and left only 275 distinct ones.
- No transfer-protocol change, so v1.10.0 interoperates with older CLI and browser peers in every direction.
A redrawn app icon, and two things that used to fail silently
- The app icon is redrawn to match the mark on floe.one: a larger bolt with rounded corners, at the proportions the website already used. The squircle keeps its depth, which the flat website favicon has no use for.
- On a Store install, Windows no longer draws a coloured square behind the icon on the taskbar, in Start, in search and in Alt+Tab. The package was missing the unplated icon assets Windows looks for, so it fell back to plating the icon; 0.2.1 only changed what colour that square was. Installs from GitHub were never affected.
- Fixed the app exiting without a word when it could not start. Release builds have no console, so a failure before the window appeared killed the process in silence. The one cause you can act on is a missing WebView2 runtime that Floe could not download, offline or behind a filtering proxy, and that now raises a message box naming it. Failures raised inside the window toolkit itself can still end the process quietly.
- Fixed Start over throwing away a typed note without asking.
CtrlRis now ignored while the cursor is in a field, and starting over from idle asks first when a note is waiting to be sent. It stays silent while a connection is being set up, and just after a send, on purpose: Start over is the way out of a connection that will not settle. Staged files are still cleared without a prompt, since the files themselves are untouched on disk. - Corrected the encryption note in the sidebar. Floe’s data channel is secured by DTLS; the note also credited SRTP, which protects the audio and video streams that Floe never sends.
- No transfer-protocol change, so Floe Desktop 0.2.2 transfers with browser and CLI peers in every direction.
A darker tile behind the Store icon
- On a Microsoft Store install, the square Windows drew behind the Floe icon took the system accent colour, which is a bright blue on a default Windows setup. It is now the brand dark, so the tile reads as one piece with the icon. Removing that square altogether came later, in 0.2.2.
- The installer and portable zip published under this tag behave exactly as 0.2.0 does. The change lives in the Store package manifest, so there is nothing to gain by downloading them.
- No transfer-protocol change, so Floe Desktop 0.2.1 transfers with browser and CLI peers in every direction.
Floe Desktop arrives on the Microsoft Store
- Floe Desktop is now on the Microsoft Store. Microsoft re-signs the package, so it installs with no “unknown publisher” warning and updates itself in the background. This is the recommended way to install it.
- The installer and portable zip on GitHub continue in parallel and are not going away. They serve machines without Store access, and they are the fallback if a Store update ever goes wrong. Those builds are unsigned, so Windows still warns on first run.
- The Show in right-click menu setting is hidden on a Store install, along with the Windows section of Settings that contains it. A packaged app’s registry writes land in a private view that File Explorer never reads, so the entry could be written but would never appear. The GitHub build still offers it.
- Both builds keep their settings in the same place, so switching between them, or between the desktop app and the
floeCLI, keeps your server address and preferences. - Desktop releases carry their own
desktop-vX.Y.Znumbers, separate from thevX.Y.Ztags that release the CLI and the server. The two lines never need to match. - No transfer-protocol change, so Floe Desktop 0.2.0 transfers with browser and CLI peers in every direction.
Floe Desktop, the first beta
- A native Windows app, and the third way to use Floe alongside the web app and the CLI. It runs the same transfer engine as the CLI, so it sends to and receives from browser peers and CLI peers with no extra setup. See Floe Desktop.
- Send files, whole folders without zipping, or a typed note. Add them with the picker, by dropping them anywhere on the window, or with
CtrlVfor files copied in File Explorer and for screenshots straight off the clipboard. - Receive with a room code or a share link, choose where files land, then open the file or reveal it in File Explorer. Nothing is ever overwritten, and received files are tagged as downloads so Windows applies its usual caution.
- A local history of the last 50 transfers, a Windows notification when one finishes, and the machine is kept awake while a transfer is connected.
- Settings cover the save folder, a Hide my IP mode that routes everything through the relay, the global-stats opt-out, the File Explorer Send with Floe entry, and a self-hosted server address with a Test button that checks the three endpoints a transfer actually needs.
- The installer is per user, so there is no administrator prompt, and uninstalling leaves your settings and history in place.
- Relayed transfers are capped at 2 GB per session, the same rule the web app and the CLI already apply. Direct transfers have no limit.
- No transfer-protocol change, so Floe Desktop 0.1.0 transfers with browser and CLI peers in every direction.
A self-hosting image fix. The CLI is unchanged.
- Fixed the self-hosted web client re-encoding every image on every request instead of caching it.
/app/.nextwas owned byrootwhile the server runs asnode, so the image cache could never be written. Pages rendered correctly throughout, which is why it went unnoticed: the only symptoms were wasted CPU on every request and anEACCESunhandled rejection in the container logs each time. This affects1.9.0, andlatestas it stood before this release. - To pick it up:
docker compose pullthendocker compose up -d. If you pinnedFLOE_IMAGE_TAG=1.9.0, move to1.9.1. docker-compose.ymlnow defaults to thelatestrelease rather thanmain, so a fresh install tracks releases instead of every merged commit. This could not ship in v1.9.0 itself:latestis created by the release, so a compose file inside that release could not have pointed at it. SetFLOE_IMAGE_TAG=mainif you prefer to stay onmain.- The CLI is identical to v1.9.0. It is republished only because the CLI and the container images share one version number, so a
floeupgrade offered by Homebrew, Scoop, or winget changes nothing for you. There is no need to update it. - The smoke test that every image must pass before a tag points at it now asserts that a repeat image request is served from cache. The existing checks all passed while this was broken, since the response stayed a valid WebP with a 200 status, so nothing in it revealed the problem.
- No transfer-protocol change, so v1.9.1 interoperates with older CLI and browser peers in every direction.
Self-hosting without a clone, on any common hardware
- Prebuilt images are published to
ghcr.io/jannskiee/floe-serverandghcr.io/jannskiee/floe-client, anddocker-compose.ymlpulls them. A working instance is two commands: download the compose file, thendocker compose up -d. No repository, no Node, no Go, nothing compiled locally. See Container Images. - Both images are published for
linux/amd64andlinux/arm64, so Raspberry Pi, Oracle Ampere, AWS Graviton, and Apple silicon run exactly the same two commands. Docker selects the right architecture automatically. - A
.envfile is genuinely optional. Every setting has a working default. - Pin a version with
FLOE_IMAGE_TAG, or pin a digest for a build that can never move. - Each architecture is built and smoke-tested on its own hardware, and a tag is published only after every architecture of both images passes, so a partly-built release is never visible. That matters because the image optimiser fails silently: when it cannot load it serves the original file rather than erroring, so a broken image would look healthy to anything that only checks whether the page loads.
- The published client no longer emits canonical links, Open Graph images, or sitemap entries pointing at
floe.one. A shared image cannot know which domain it will be served from, so it claims nothing rather than advertising somebody else’s site. To use your own domain, build the client withNEXT_PUBLIC_SITE_URLset. - Contributors build from source with
docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --build. - Both images move to Node 24, the Active LTS. The server was on Node 20, a Maintenance release.
- CLI:
floe versionand the help text now point atfloe.one/docsrather than the retireddocs.floe.one, and the WebRTC stack moves to pion 4.2.18. - 32-bit ARM (
linux/arm/v7) is not published: Node dropped support for it and no prebuilt image-processing binaries exist. - No transfer-protocol change, so v1.9.0 interoperates with older CLI and browser peers in every direction.
The 2 GB relay cap now applies to the CLI, plus honest receiver errors
floe sendnow enforces the same 2 GB relay session cap as the web app. Once the connection is established, the sender checks the selected route: if it runs through the TURN relay and the queued files total more than 2 GB, the transfer is blocked before any data moves, with a clear error. Direct connections keep no size limit, and a connection whose path cannot be determined is never blocked. See The 2 GB Relay Limit.- Fixed the receiver treating a sender that disconnected before the first file as a successful transfer:
floe receiveexited silently as if nothing was expected, and a multi-file batch interrupted between files was reported as complete. Both cases now end with a clear error describing what actually arrived. - CLI errors no longer print the full usage reference after the message. A failed transfer or an expired code now shows the one-line error alone.
- No transfer-protocol change, so v1.8.0 interoperates with older CLI and browser peers in every direction.
Stalled transfers now fail fast with clear errors
- Fixed transfers freezing forever when the connection silently broke right after setup. The receiver now reports “connected, but no data arrived from the sender” within 30 seconds if the transfer never starts, and “transfer stalled” with exact byte progress if data stops flowing mid-file for a full minute, instead of sitting on a frozen progress bar until you press Ctrl+C. These stalls are rare, but when one happened there was no way to tell it apart from a slow transfer.
- Fixed
floe sendwaiting up to two minutes after the receiver declined the transfer or exited. It now reports “connection closed while waiting for the receiver” in about a second. - Web app: the share link now appears only once the server has confirmed your room. This closes a rare race where a receiver that followed the link extremely quickly could be mistaken for the sender and fail with a role error.
- Updated the CLI’s WebRTC stack (Pion) to the current releases.
- No transfer-protocol change, so v1.7.6 interoperates with older CLI and browser peers in every direction.
Accurate progress on slow connections, and a CLI relay fix
- Fixed the sender’s progress running far ahead of the receiver. The sender counted bytes handed to the connection’s send buffer rather than bytes that actually reached the other side, so on slower or relayed connections its bar raced ahead by up to 8 MB, froze for up to a minute while the buffer drained, moved to the next file before the receiver finished the previous one, and showed “All Files Sent!” while the receiver was still downloading. The sender now reports delivered bytes: both sides move together at the real network speed, the file counter stays in step, and completion means the receiver has everything.
- Fixed the receiver’s progress bar barely updating since the larger transfer blocks introduced in v1.7.3. It could sit still for minutes on slow connections (and never move at all for files under 6.25 MB), which looked like a stalled transfer. It now updates at least every 1 MB regardless of block size.
- Fixed
floe sendgiving up with a “backpressure stall” error on relayed connections slower than roughly 70 KB/s. The CLI now aborts only when the connection makes no progress at all for a full minute, instead of whenever draining simply takes longer than a minute. - Web app: the connection badge tooltip and the Network Relay Fallback description now explain that direct peer-to-peer connections are the norm even across different networks such as mobile data, and that the relay is only a fallback used when a direct path cannot be established.
- No transfer-protocol change, so v1.7.5 interoperates with older CLI and browser peers in every direction.
Faster connection setup
- Fixed connections taking 20 to 30 seconds to establish on machines running VPN or virtual machine software (Tailscale, VMware, WSL, Hyper-V). Two causes were addressed: the signaling server handed every client a redundant list of eight relay endpoints where three suffice, and the CLI probed dead auto-configuration network interfaces during setup. The server-side fix is already live and speeds up all existing versions, browser included; this release adds the CLI-side hardening so connections stay fast against any server, including self-hosted ones.
- Added an advanced
--ifaceflag to restrict the CLI to specific network interfaces by name (for example--iface Ethernet), useful for pinning a transfer to a chosen network. Most users never need it. See the flags reference. - Web app: opening a fresh share link in a tab that already had Floe open now joins the new room correctly instead of reusing the old session.
- No transfer-protocol change, so v1.7.4 interoperates with older CLI and browser peers in every direction.
Faster CLI transfers, and a browser-to-CLI reliability fix
floe sendnow sends file data in larger blocks, sized to what the connection negotiates (up to 256 KB) rather than a fixed 16 KB. On fast paths such as a local network or a direct connection, this removes most of the per-block overhead and noticeably increases throughput. Relayed or slower connections are unaffected, since their speed is set by the link rather than the block size.- Fixed browser-to-CLI transfers that could fail with a timeout when the person running
floe receivetook more than 15 seconds to accept the incoming files at the prompt. The browser now waits as patiently as the CLI already did. - No transfer-protocol change, so v1.7.3 interoperates with older CLI and browser peers in every direction.
CLI: share links keep the room secret in the URL fragment
floe sendnow prints ahttps://floe.one/#room=<id>link. The room id sits in the URL fragment (after the#), which a browser never sends to the web server, never puts in theRefererheader, and never exposes to pageview analytics. Previously it was a?room=query parameter that could reach those places when a recipient opened the link in a browser. This brings the CLI in line with the web app.floe receiveresolves a#room=link, a legacy?room=link, or a short code, so links shared by any version keep working.- No transfer-protocol change, so v1.7.2 interoperates with older CLI and browser peers in every direction.
Reliable global-counter reporting for the CLI
- Fixed CLI transfers not always being counted in the global homepage counter. The receiver’s byte-count report was sent in the background and could be cut short when the sender closed the connection and the process exited, so larger transfers (several GB and up) were frequently missed and smaller ones counted only intermittently.
- The report now completes before the program exits, so a successful CLI transfer of any size contributes exactly once. The report still carries only the byte count (never file names or contents), still never blocks or slows the transfer, and opting out with
--no-reportorFLOE_NO_STATS=1is unaffected. - Browser transfers were never affected by this issue.
Global transfer counter with opt-out
- Added a public, all-time counter of total bytes transferred across every Floe user, shown on the homepage with a rolling-number animation. The number rolls up from zero on each visit and ticks higher as transfers complete worldwide.
- The counter is fed without ever touching your files. After a transfer finishes, only the receiving side reports the byte count (never file names or contents). The sender never reports. The stored value is a single anonymous total, not linked to any user, transfer, or IP address. See Security and Privacy for the full data-handling note.
- The CLI receiver now contributes to the global counter. The total is viewable only in the browser; the CLI never fetches or displays it.
- Both the browser receiver and the CLI receiver support opting out. Browser: uncheck “Contribute to global stats” on the receiver view (saved to your browser). CLI: pass
--no-reporttofloe receive, or setFLOE_NO_STATS=1in your environment for a permanent opt-out. The transfer is unaffected either way. - Self-hosters can opt in by pointing the server at a free Upstash Redis database (
UPSTASH_REDIS_REST_URLandUPSTASH_REDIS_REST_TOKEN). Without it, the counter still works but resets on restart. See Configuration.
Protocol version negotiation
- Added a wire protocol version that the sender and receiver exchange when a transfer starts. It is separate from the release version (1.6.x), so peers on different releases still transfer normally. A patch or minor difference such as v1.5.4 and v1.5.5 is never a conflict and is never blocked.
- If a future release ever changes the wire format in a breaking way, the two sides now detect it before any file data moves and print a clear “your floe is too old, run
floe update” message (or “ask the other side to update”) instead of failing with a confusing error or a corrupt file. - Works in every direction: CLI-to-CLI, browser-to-CLI, and CLI-to-browser. Older peers that predate this change are treated as the baseline protocol and stay fully compatible.
floe update permission fix- Fixed
floe updatefailing with “permission denied” when floe is installed in a root-owned directory such as/usr/local/binon Linux and macOS. The updater now downloads and extracts as the current user, installs directly when the location is user-writable (for example~/.local/bin), and automatically requests sudo only for the final atomic swap when it is not. To upgrade from an older version one time, runsudo floe update; after that plainfloe updateworks.
CLI progress bar fix
- Fixed the transfer progress bar printing a new line for every percentage on narrow or Windows terminals. The bar now sizes itself to the terminal width so the line never wraps, and it updates in place on a single line per file.
Installer and self-update download fix
- Fixed a 404 when installing or updating floe. The install scripts (
install.sh,install.ps1) and the built-infloe updaterequested the release archive with a leading “v” in the version (for examplefloe_v1.5.2_linux_arm64.tar.gz), but the published asset name omits it (floe_1.5.2_linux_arm64.tar.gz). All download paths now use the correct filename. This affected every platform and architecture, including Raspberry Pi (linux/arm64).
CLI stability fix
- Fixed a rare concurrent-write panic in the CLI signaling client. Rapid ICE candidate negotiation could trigger simultaneous WebSocket writes from separate goroutines; all writes are now serialized.
CLI output improvement
- The
Sendingsummary line (file name and total size) now appears above the sharing box, so you can see what is being sent before the peer connects.
File summary on both sides
- Both the sender and the receiver now see a file count and total size before and after the transfer. Example:
Sending 3 files · 11.8 MBon the sender side andIncoming 3 files · 11.8 MBon the receiver side.
CLI-to-CLI transfer fix
- Fixed an error reported by the CLI sender after a successful CLI-to-CLI transfer. The transfer completed correctly but the sender exited with an error code. It now exits cleanly.
One-command install and self-update
floe updatenow works on all platforms (script installs, manual installs). It downloads, verifies, and replaces the running binary in one step.- Re-running the install script (
curl -fsSL https://floe.one/install.sh | shorirm https://floe.one/install.ps1 | iex) also upgrades an existing install in place. - If floe was installed via Homebrew, Scoop, or Winget,
floe updatedetects this and prints the correct package manager command instead. - Fixed a browser receiver bug where a
Bufferview was retained across chunk boundaries instead of being copied, which could corrupt received data. - Security: updated
ws,esbuild, andpostcsstransitive dependencies to address published advisories.
Rich transfer summary
-
At the end of each transfer, the CLI now prints a boxed summary with the total data transferred, elapsed time, and average speed. Example:
-
The receiver summary also includes the
Saved topath.
Transfer reliability and browser fixes
- Fixed several CLI transfer sync bugs that could cause stalled or incomplete transfers, especially in CLI-to-CLI sessions. Added cross-implementation loopback tests to prevent regressions.
- Fixed an issue where the in-app browser detection could steal the receiver slot from a legitimate peer, preventing the transfer from starting.
- Fixed duplicate WebRTC signal handling that could break transfers after a reconnect.
- Redesigned the in-app browser warning page for clarity.
- Upgraded the CLI to Pion WebRTC v4 (includes Pion DTLS v3).
- Performance: improved browser-to-browser transfer throughput with better backpressure tuning.
Initial public release
- Browser-based peer-to-peer file transfer at floe.one. No account, no installation, no file storage.
floeCLI for macOS, Linux, and Windows. Fully interoperable with the browser client.- End-to-end DTLS encryption on all transfers, direct and relayed.
- Optional TURN relay fallback for peers behind strict firewalls or carrier-grade NAT (capped at 2 GB per session).
- Self-hosting support via Docker Compose. See Self-Hosting.
- Mintlify documentation site at docs.floe.one.