f3b8190e6815e8c67b68292b6fefa7e4c0e087a5
- monsoon.spec: two subpackages (monsoon desktop, monsoon-server headless) with vendored deps, desktop/appstream validation, and systemd integration - data/monsoon-server.service: runs as dedicated monsoon user with StateDirectory/ConfigurationDirectory/CacheDirectory - dist.sh: generates source + vendored dependency tarballs for offline builds - .copr/Makefile: SCM integration for automated COPR builds Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Monsoon
A fast BitTorrent client for the GNOME desktop and headless servers, built on the Vortex io-uring engine.
Two interfaces:
- Desktop app -- Tauri + Svelte GUI with GNOME integration
- Headless server -- REST API + WebSocket + web GUI for remote/LAN deployment
Screenshots
Torrent List
Activity
Details
Files
Dependencies
Fedora
sudo dnf install gtk3-devel webkit2gtk4.1-devel libsoup3-devel \
pango-devel gdk-pixbuf2-devel glib2-devel libappindicator-gtk3-devel
The GTK dependencies are only needed for the desktop app. The headless server has no system library requirements beyond a working Rust toolchain.
Toolchain
Desktop App
Development
pnpm install
cargo tauri dev
Release
pnpm install
cargo tauri build
The release binary is at target/release/monsoon with the frontend assets embedded.
Install
sudo install -Dm755 target/release/monsoon /usr/local/bin/monsoon
sudo install -Dm644 data/cafe.lair.monsoon.desktop /usr/share/applications/cafe.lair.monsoon.desktop
sudo install -Dm644 data/cafe.lair.monsoon.metainfo.xml /usr/share/metainfo/cafe.lair.monsoon.metainfo.xml
sudo install -Dm644 src-tauri/icons/icon.png /usr/share/icons/hicolor/256x256/apps/cafe.lair.monsoon.png
sudo install -Dm644 src-tauri/icons/128x128.png /usr/share/icons/hicolor/128x128/apps/cafe.lair.monsoon.png
sudo install -Dm644 src-tauri/icons/32x32.png /usr/share/icons/hicolor/32x32/apps/cafe.lair.monsoon.png
sudo gtk-update-icon-cache /usr/share/icons/hicolor/
Headless Server
Building
cd monsoon-web && pnpm install && pnpm build && cd ..
cargo build --release -p monsoon-server
Running
# With web GUI (run from the repo root, or set MONSOON_WEB_DIR)
cargo run --bin monsoon-server
# Or with explicit web asset path
MONSOON_WEB_DIR=/path/to/monsoon-web/dist monsoon-server
The server listens on 0.0.0.0:3000 by default. Open http://server-ip:3000 in a browser for the web GUI.
REST API
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/torrents |
List all torrents |
GET |
/api/torrents/:id |
Get torrent details |
POST |
/api/torrents |
Add torrent (JSON: magnet or file path) |
POST |
/api/torrents/upload |
Upload a .torrent file (multipart) |
DELETE |
/api/torrents/:id |
Remove torrent |
POST |
/api/torrents/:id/pause |
Pause torrent |
POST |
/api/torrents/:id/resume |
Resume torrent |
GET |
/api/config |
Get server configuration |
PUT |
/api/config |
Update server configuration |
Examples
# Add a magnet link
curl -X POST http://localhost:3000/api/torrents \
-H "Content-Type: application/json" \
-d '{"type": "magnet", "magnet": "magnet:?xt=urn:btih:..."}'
# Upload a .torrent file
curl -X POST http://localhost:3000/api/torrents/upload \
-F "file=@/path/to/file.torrent"
# List torrents
curl http://localhost:3000/api/torrents | jq
# Pause a torrent
curl -X POST http://localhost:3000/api/torrents/TORRENT_ID/pause
WebSocket
Connect to ws://server-ip:3000/ws for real-time event streaming. Events are JSON:
{"type": "metrics", "id": "...", "downloadSpeed": 1234, "uploadSpeed": 56, "numPeers": 12, "piecesCompleted": 42}
{"type": "stateChanged", "id": "...", "newState": "seeding", "name": "..."}
{"type": "metadataComplete", "id": "...", "name": "...", "totalPieces": 100, "totalSize": 1073741824}
Queue Management
Configure in ~/.config/monsoon/config.toml:
[server]
max_concurrent_downloads = 3
min_peers_before_queue = 2
seed_completed_by_default = true
webhook_url = "http://localhost:8080/hook"
- max_concurrent_downloads -- new torrents are queued when all slots are full; the next queued torrent auto-starts when a slot frees up
- min_peers_before_queue -- if a torrent has fewer peers than this and download speed is below 1 KiB/s for 30 consecutive seconds, it rotates to the back of the queue
- seed_completed_by_default -- when
false, completed torrents are paused instead of seeding - webhook_url -- POST a JSON payload to this URL when a torrent completes (for automation: Jellyfin scans, file movers, etc.)
Configuration
Monsoon follows XDG directory conventions:
| Purpose | Path |
|---|---|
| Config | ~/.config/monsoon/config.toml |
| Downloads | ~/.local/share/monsoon/downloads/ |
| Torrent registry | ~/.local/share/monsoon/torrents.json |
| Logs | ~/.local/state/monsoon/monsoon.log |
| DHT cache | ~/.cache/monsoon/dht_bootstrap_nodes |
License
GPL-3.0-or-later
Languages
Rust
56.1%
Svelte
34.6%
TypeScript
6.6%
CSS
1.8%
Shell
0.4%
Other
0.4%



