anmolkapil
plexo
Speed up downloads by combining multiple network connections in parallel
Documentation snapshot
README 快照
翻译暂时拿不到。
机器翻译的项目简介,仅供参考。原文在下方,也可以直接用浏览器自带的整页翻译 (Chrome / Edge 点地址栏右侧的翻译图标,或用右键菜单里的「翻译成中文」)。
下面正文是项目自己的英文 README。想读全文就用浏览器自带的整页翻译: Chrome / Edge 点地址栏右侧的翻译图标,或用右键菜单里的「翻译成中文」; 手机浏览器一般在菜单里。
本页保存的是公开项目资料快照,阅读过程不需要连接 GitHub。
Plexo
A fast download manager for Windows and macOS that speeds up downloads by pulling chunks in parallel across multiple network connections at the same time.
For example, if your computer has:
- Wi-Fi
- Ethernet
- USB-tethered phone (iPhone or Android)
Plexo can utilize all of them simultaneously to download the same file.
https://github.com/user-attachments/assets/e57728f4-fb63-441f-839c-174eef954b17
⚠️ Before you start
Using Android USB tethering on macOS?
macOS does not natively provide an RNDIS driver, so Android phones with USB tethering enabled won’t appear as network interfaces out of the box (this is also why legacy kernel extensions like HoRNDIS stopped working on Apple Silicon and modern macOS).
To use your Android phone’s connection over USB, install TetherKit — a kext-free, user-space RNDIS driver.
See Using a USB-tethered Android phone for setup instructions.
Plexo can only route traffic through connections that your operating system recognizes as network interfaces.
Why Plexo?
A single TCP connection rarely saturates your actual bandwidth. Even when your computer has multiple active networks — such as Wi-Fi and a tethered mobile phone — the operating system routes all traffic through a single default gateway, leaving the other interfaces completely idle.
Plexo changes that: it splits the file into independent byte ranges and downloads them simultaneously through distinct physical network interfaces.
┌── Wi-Fi (IP: 192.168.1.40) ────┐
│ │
File ──→ Split ─────┼── Ethernet (IP: 10.0.0.12) ────┼──→ Assembled File
│ │
└── USB Tether (IP: 172.20.10.3) ┘
Multiple networks → concurrent HTTP range requests → aggregated bandwidth
Features
- 🚀 Multi-interface, multi-connection downloads — splits files into fixed 8 MB chunks and fans them out across worker connections bound to specific network interfaces (up to 8 parallel connections per interface, 32 total).
- 🔌 Hardware interface detection — queries Windows adapters via PowerShell
Get-NetAdapterand macOS hardware ports vianetworksetupso Wi-Fi, Ethernet, tethered iPhones, and Thunderbolt bridges are labeled by real device names instead of bare BSD names (en0,en6). - ⚖️ Dynamic work-stealing queue — chunks are leased from a shared pending queue; faster networks pull more chunks instead of waiting for slower connections to finish.
- ⏸️ Resumable downloads — pausing cleanly aborts in-flight socket connections while preserving downloaded
part-Nchunk files on disk. - 💾 Relaunch recovery — interrupted downloads are restored as paused after Plexo restarts, with progress and part files preserved in application data.
- 🛡️ Safe, integrity-checked resume — re-verifies remote
ETagandLast-Modifiedvalidators before resuming, refusing to resume (rather than corrupting the file) if the server-side file has changed. - 🔁 Automatic retry with backoff — failed chunks are automatically returned to the queue and retried with exponential backoff (up to 5 retries, 1s–15s backoff).
- 💤 Stall detection — automatically drops and re-queues connections that remain open but silent (>20s without incoming data).
- 💾 Upfront disk-space verification — verifies free disk space before writing any temporary part files.
- 🔀 Mid-download redirect handling — transparently follows 3xx HTTP redirects (up to 5 hops) during probing and individual chunk downloads.
- 📊 Real-time telemetry — live throughput graphs, rolling-window ETA calculation, and per-connection transfer stats.
- 🗺️ Interactive progress grid — 1:1 visual map of individual 8 MB chunks, color-coded by the network interface that fetched each chunk with accurate per-network byte attribution.
- 🎨 Network customization — rename and recolor physical network interfaces with persistent user preferences.
- 🌙 Dark mode
How it works
Instead of downloading a file linearly over a single socket, Plexo requests arbitrary slices of the file simultaneously across multiple physical network interfaces. Three core technical primitives make this work:
1. HTTP range requests (206 Partial Content)
Most modern HTTP servers support byte-level slicing:
GET /ubuntu-26.04.1-desktop-amd64.iso HTTP/1.1
Host: releases.ubuntu.com
Range: bytes=8388608-16777215
Servers advertise this capability with the Accept-Ranges: bytes response header and reply with HTTP status 206 Partial Content. Because byte slices are stateless and independent, Plexo can request dozens of chunks at once, in any order, and stitch them together later.
Probing before downloading
Before starting a multi-connection download, Plexo sends a 1-byte ranged GET (Range: bytes=0-0), following any redirects:
- Unlike a
HEADrequest (which servers and CDNs frequently misreport), receiving a206 Partial Contentresponse conclusively proves that range requests are supported and functional. - The probe response provides the total file size (
Content-Range/Content-Length), suggested filename (Content-Disposition), and cache validators (ETagandLast-Modified). - If the server answers with
200 OK(ignoring theRangeheader), Plexo falls back to a standard single-connection stream instead of failing.
2. Multi-interface socket binding via localAddress
Every active network interface on your computer has its own local IP address — Wi-Fi might be 192.168.1.40, while a USB-tethered phone is 172.20.10.3.
A standard TCP socket leaves interface selection to the operating system’s routing table. However, Node.js allows outbound HTTP/HTTPS requests to explicitly bind to a specific local IP using the localAddress option:
https.request({
hostname: 'releases.ubuntu.com',
path: '/ubuntu-26.04.1-desktop-amd64.iso',
localAddress: '172.20.10.3', // Forces this connection through the USB tether
headers: {
Range: 'bytes=8388608-16777215'
}
})
This single option is Plexo’s entire multi-network routing engine:
- No virtual network adapters or VPN tunnels
- No packet bonding or link aggregation
- No kernel extensions (
kext) or root privileges - Zero native C/C++ dependencies
3. Dynamic work-stealing queue
If you statically divide a 6 GB file into equal shares (e.g. 3 GB on Wi-Fi and 3 GB on mobile data), the total download speed is bottlenecked by the slower network.
Instead, Plexo uses a dynamic work-stealing queue:
- The file is split into fixed 8 MB chunks.
- All chunks enter a centralized pending queue.
- A pool of worker connections (up to 8 per interface, 32 total) continuously lease the next chunk from the queue as soon as they become free.
- Faster interfaces finish chunks quicker and immediately pick up new ones; slower interfaces pull fewer chunks.
Shared Pending Queue: [Chunk #4] [Chunk #5] [Chunk #6] [Chunk #7] [Chunk #8] ...
↑ ↑ ↑
Worker 1 Worker 2 Worker 3
(Wi-Fi) (Ethernet) (USB Tether)
Work distribution is dynamically proportional to each interface’s real-time throughput. If one network slows down or disconnects, remaining workers continue draining the queue without stalled shares.
4. File reassembly & stream pipeline
Each worker writes its assigned byte range directly to an isolated temporary file on disk (part-0, part-1, … part-N).
Once the queue is drained and all chunk promises resolve:
- Plexo streams each
part-Nfile sequentially into the final destination file using Node.js streams (createReadStreampiped intocreateWriteStreamwith{ flags: 'a' }). - The temporary chunk directory is cleaned up.
- The assembled file is verified against the expected byte length.
Downloads are resumable
When you pause a download:
- Plexo aborts all active HTTP socket connections via
AbortController. - All completed
part-Nfiles remain cached on disk in a temporary directory.
When you resume:
- Validator check: Plexo sends a probe request to compare the server’s current
ETagandLast-Modifiedheaders against the values recorded when the download started. - Safe resume: If the validators match, Plexo checks which
part-Nfiles are already complete on disk, skips them, and queues only the remaining chunks. - Guard against corruption: If the file on the server has changed, Plexo refuses to resume to prevent combining incompatible slices into a corrupt file.
Download manifests and partial data are stored under Plexo’s application-data directory. If Plexo quits or crashes during a transfer, it restores that transfer as paused on the next launch. Explicitly cancelling or removing a download still deletes its partial data.
What is a chunk?
A chunk is the atomic unit of work in Plexo:
- Size: Exactly 8 MB (with the final chunk sized to the remaining bytes).
- Transport: One independent HTTP range request (
Range: bytes=START-END). - Storage: Written directly to an isolated
part-Nfile in the download’s temp directory. - Assignment: Leased to an individual worker socket bound to a specific network interface.
Chunk #0 → Range: bytes=0-8388607 → part-0 (Wi-Fi)
Chunk #1 → Range: bytes=8388608-16777215 → part-1 (Ethernet)
Chunk #2 → Range: bytes=16777216-25165823 → part-2 (USB Tether)
Why 8 MB?
8 MB provides the optimal balance: large enough to minimize HTTP connection overhead and TLS handshakes, yet small enough to keep the work-stealing queue fluid, ensure fine-grained load balancing across mismatched connections, and keep retries cheap (a failed or stalled connection only discards at most 8 MB).
What is the progress grid?
The progress grid provides a real-time visual map of the entire download.
Every 8 MB chunk maps 1:1 to its own square in the grid. Square #N directly corresponds to the Chunk #N badge shown in the active streams table, allowing you to cross-reference active connections with their location in the file.
Active Streams:
[Wi-Fi] → Chunk #4
[Ethernet] → Chunk #5
[USB Tether] → Chunk #6
Progress Grid:
[#1][#2][#3][#4][#5][#6][#7][#8]...
- 1:1 chunk mapping: Every square represents an atomic 8 MB chunk of the file.
- Accurate per-network attribution: Each square is colored by the network interface that delivered the dominant share of its bytes. If a chunk changes hands mid-flight (due to a dropped connection, retry, or pause/resume), Plexo tracks per-network byte tallies so each interface’s contribution is accurately credited.
- Joint contributor breakdown: Hovering over any square displays the chunk index, bytes downloaded, and an exact breakdown of contributing networks (e.g.,
Wi-Fi 70% · Ethernet 30%). - Responsive & scrollable: Squares maintain a fixed, readable size across all downloads. The grid wraps to fit the window width and smoothly scrolls past 6 rows on large files.
Getting started
Plexo currently doesn’t have pre-built releases, so you’ll need to run it from source.
Requirements
- Windows 10/11 or macOS: Windows uses its built-in Windows PowerShell for adapter metadata; macOS uses
networksetup. If metadata is unavailable, Plexo falls back to interface names. - Node.js: 22.12+ (Node 22 LTS recommended).
- npm: v9+ recommended.
Run Plexo locally
Clone the repository:
git clone https://github.com/anmolkapil/plexo.git
cd plexo
Install dependencies:
npm install
Start the application in development mode:
npm run dev
Build the macOS app
To package Plexo as a standalone macOS application bundle:
npm run build:mac
The compiled application will be generated at:
dist/mac/Plexo.app
Note on Gatekeeper: The app is unsigned because it is not distributed with a paid Apple Developer certificate. However, because you compile it locally on your machine, macOS will not apply the quarantine flag (
com.apple.quarantine). Gatekeeper only quarantines files downloaded from the web (via browsers, curl, etc.), so your locally builtPlexo.appwill launch cleanly without quarantine warnings.
Build the Windows app
Run these commands from PowerShell in the project directory:
npm install
npm run build:win
The installer is generated at dist/plexo-1.0.0-setup.exe. For an unpacked app, run
npm run build:unpack and launch dist/win-unpacked/plexo.exe.
Local builds are unsigned.
Windows uses native window controls, Ctrl+V hints, File Explorer integration, and Windows Network Settings. Download filenames are normalized to Windows filename rules.
USB tethering on Windows
Enable USB tethering on your phone and check that its adapter appears in Windows Network Settings. Install the phone manufacturer’s Windows driver if Windows does not recognize it. TetherKit is only needed for the macOS setup below.
Each selected network needs a working IPv4 connection and a route to the download server. Adapter detection does not guarantee Internet access: VPN, virtual, and isolated adapters may also appear. Check per-network latency and transfer stats. Combined throughput depends on the networks, Windows routing, and the server; it needs testing with your particular connections.
Linux packaging remains available but has not been validated.
Using a USB-tethered Android phone
Android USB tethering requires an additional setup step on macOS.
macOS lacks native support for the RNDIS (Remote Network Driver Interface Specification) protocol. An Android phone with USB tethering enabled will charge and support MTP/ADB, but macOS will not expose it as a network interface (this is also why legacy kernel extensions like HoRNDIS stopped functioning on modern macOS and Apple Silicon).
Install TetherKit
TetherKit is an open-source, kext-free, user-space RNDIS driver that makes Android USB tethering available as a standard network interface on macOS.
Install it via Homebrew:
brew install XiaoMiku01/tap/tetherkit
Steps:
- Connect your Android device via USB.
- On your phone, navigate to Settings → Network & Internet → Hotspot & tethering and enable USB tethering.
- Once TetherKit is active, macOS registers the device as a network interface.
- Open Plexo — the new interface will be automatically detected and ready to carry download chunks.
Special thanks to @XiaoMiku01 for developing and open-sourcing TetherKit!
Contributing
Contributions are welcome! Whether you’re optimizing download concurrency, improving UI responsiveness, or testing new tethering setups:
- 🐛 Fix bugs & edge cases
- 🚀 Improve download engine & socket throughput
- 🌐 Expand multi-interface detection to other platforms (Linux)
- 🎨 Enhance UI/UX and dark mode styling
- 🧪 Test diverse multi-network environments (5G tethering, Wi-Fi 6, 10GbE)
- 📖 Improve documentation & guides
For development setup, coding standards, and PR workflows, see CONTRIBUTING.md.
Tech stack
Plexo is built with:
- Electron — desktop runtime
- React 19 — declarative UI
- TypeScript — end-to-end type safety
- Zustand — lightweight client state management
- electron-vite — fast HMR and build tooling
- electron-builder — macOS packaging
License
MIT — see LICENSE.
Official distribution
获取与安装
暂未发现可确认的官方软件包地址
当前 README 快照没有出现 npm、PyPI、Crates.io、pub.dev 等官方包页链接。本站不会根据仓库名称猜测下载地址。
本站不托管项目文件;需要安装时,请以项目维护者发布的官方文档为准。
Before installing
使用前核验
本站保存公开资料用于阅读,不代表安全审计或功能背书。安装前请核对许可证、依赖来源和发布签名,不要直接运行来源不明的二进制文件或高权限脚本。