Skip to content

Repository files navigation

PeerZero

Important

For educational and personal use only. PeerZero is a local-only tool for learning about BitTorrent, peer-to-peer networking, and web development. Only download content you are legally entitled to - Linux distributions, public-domain works, Creative Commons media, and files you own or have permission to share. You alone are responsible for what you download and for complying with copyright law where you live. The maintainers do not endorse or facilitate copyright infringement and will honor valid legal notices.

A local-only BitTorrent client with a built-in video player for macOS. Search, paste a magnet link, or drop a .torrent, then watch it download live - and play the video right in the app, even before it finishes. The in-app player is macOS-only; the Windows and Linux builds are download-only. No account, no cloud, nothing hosted - it all runs on your own machine.


Download

Grab the desktop app from the latest release:

OS File In-app player
macOS (Apple Silicon) .dmg Yes (native mpv)
Windows (x64) .exe setup, or .msi No, download-only
Linux (x64) .deb No, download-only

On Windows and Linux everything except in-app playback works the same - search, download, the file tree, reveal-on-disk, and self-update; finished files open in your own player.

The app self-updates on new releases; you can also jump to any version (forward or back) from Settings -> Advanced -> the release table. Builds are unsigned for now, so on macOS the first launch needs a one-time bypass: drag PeerZero.app to Applications, then run this once (macOS quarantines unsigned downloads and reports them as "damaged"; this clears the flag):

xattr -dr com.apple.quarantine /Applications/PeerZero.app

Windows SmartScreen will likewise warn on an unsigned installer: choose More info -> Run anyway.

Canary builds. Every push to canary publishes an early pre-release (an amber-iconed "PeerZero" that installs beside the stable app, so you can run both). Install one, or switch between canary builds, from the same Settings -> Advanced release table. Canary is macOS-only - Windows and Linux ship on stable releases only.


What it does

  • Search public indexes from the Search tab, or paste a magnet link / drop a .torrent.
  • Download with a real WebTorrent client over the normal TCP/uTP/DHT swarm. Pause, resume, remove, and watch live progress (speed, peers, ETA) stream over a WebSocket into the Transfers tab.
  • Watch it in the app (macOS). On the Mac app, click any video and it plays in a built-in Netflix-style player that streams as the file downloads, so you can start before it finishes. It decodes through native mpv (hardware-accelerated) for the containers and codecs a browser refuses - MKV, HEVC/H.265, AV1, AC3/E-AC3 - with embedded subtitles rendered natively. No external player like VLC, and nothing to install: libmpv ships inside the app. Reopen a video and it resumes a few seconds before where you left off (remembered per file, across restarts). The Windows and Linux builds are download-only (no in-app player); open finished files in your own player.
  • Browse every file. Expand a torrent to see its file tree with per-file progress; play or reveal any single file.
  • Stays a downloader. Completed torrents auto-stop instead of seeding.
  • Runs entirely locally. Nothing is uploaded to a server; downloads land in ~/Downloads/PeerZero by default (change it any time in the app's Settings).

Run from source

1. Install the prerequisites (one-time)

Install these two yourself first - each link has a normal installer:

  • Bun - runs the app, including the download engine · bun.sh
  • Node.js - runs the dev tooling (turbo, Next.js), pick the LTS build · nodejs.org

2. Get the project and start it

Open your terminal and run these, one at a time:

bunx gitpick nrjdalal/PeerZero   # download the project (no git needed)
cd PeerZero
bun install
bun run dev

When it's ready it prints a URL - open it in your browser:

http://peerzero.localhost:1355

Press Ctrl+C to stop; run bun run dev again to restart.

Updating later

Re-download the latest code with bunx gitpick nrjdalal/PeerZero, then bun install. You rarely need to - the app keeps its trackers and indexes fresh on its own in the background (see How updates work below).


How it works

Two Bun processes start together with bun run dev:

Service Runtime Role
web/next Bun Next.js UI + the in-app video player
api/hono Bun API layer + the in-process WebTorrent download engine

The download engine runs in-process inside the Hono API (a Bun process), so a torrent operation is a direct function call, not an HTTP hop. WebTorrent's two Bun-incompatible native addons are kept out of the process: WebRTC (node-datachannel) is neutralized by a stub plugin (api/hono/src/lib/torrent/webrtc-stub.mjs, preloaded via bunfig.toml in dev/test and applied at bundle time for the build) and uTP (utp-native) is disabled with { utp: false }; both otherwise crash Bun on an unsupported libuv function. Peers are found via the DHT plus udp/http trackers over TCP. The engine sits behind a small typed seam (api/hono/src/lib/torrent/engine.ts), so it could later be swapped for another client.

The video player is native mpv (libmpv), macOS-only: mpv renders through its OpenGL render API into a native layer behind the transparent webview, with the HTML control overlay on top (see desktop/README.md), for hardware decode + native subtitle rendering. libmpv is bundled into the app, so there is nothing to install. The Windows/Linux builds and any plain browser have no in-app player - PeerZero is Mac-first, so those are download-only (a playable file reveals on disk instead). A cross-platform WebAssembly player once filled that gap; see .github/notes/libmedia-player.md for how it worked and how to bring it back. The API serves each file over an HTTP Range endpoint (/api/torrents/:infoHash/stream/:fileIdx), so playback starts while the download is still in flight.

Dev URLs are named .localhost hosts served by portless (bunx portless list shows them). PORTLESS=0 bun run dev uses plain ports instead (web :9410, api :9336). The packaged desktop app picks a free port per launch, so several copies can run side by side.

How updates work

The app reads its provider/tracker/directory data from a committed, encoded registry (api/hono/src/lib/torrent/registry.json). In the background - once at startup, then every few hours - it refreshes that data, in order of preference:

  1. Locally, straight from the upstream lists (freshest).
  2. If those are blocked on your network, from the canary mirror, which a scheduled job keeps up to date from an unblocked environment.
  3. Otherwise it keeps the last good copy it had.

All of this is non-blocking: the UI is always served instantly from the in-memory copy while refreshes happen in the background. No git pull required to stay current.


Configuration

Everything works out of the box with no config at all - the app is local-first and defaults every setting. To tweak, set any of these as environment variables (no .env file needed). Highlights:

Variable Default What it does
TORRENT_DOWNLOAD_DIR ~/Downloads/PeerZero Where finished files land (also changeable in the app's Settings)
TORRENT_MAX_CONNS 25 Per-torrent connection cap (kept low to be gentle on home routers)
REGISTRY_SYNC_URL canary mirror Where background refresh falls back to; set to any non-URL (e.g. off) to disable

See packages/env/src for the full list of overridable variables and their defaults.


Built on top of ZeroStarter.

Important

Reminder: BitTorrent is a neutral transport; how it's used is up to you. Use PeerZero only for content you have the legal right to download (for example Linux ISOs, public-domain and Creative Commons media, or files you own). You are solely responsible for your downloads and for obeying the law in your jurisdiction.

About

A local-only BitTorrent client in one web UI, with live download progress.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages