Dark, terminal-inspired qBittorrent WebUI built with React. The interface keeps the qBittorrent API surface close at hand while using a grey scale palette, orange accent, dense torrent rows, sortable columns, a queue position column with reorder controls, tag filters, quick tag editing, settings, and add-torrent workflows.
- Sortable torrent table (name, status, progress, down/up speed, ratio, added date) with a sticky header and toolbar.
- Status filters for all, active, downloading, seeding, stopped, and stalled torrents, plus category filters, all with live counts.
- Multi-select tag filters with AND matching: a torrent must carry every selected tag to show.
- Search bar matching name, hash, category, tags, status, and save path.
- Multi-select rows with Shift, Cmd, or Ctrl for resume, stop, recheck, and remove actions.
- Remove confirmation modal with an optional
Delete downloaded datacheckbox (off by default). - Add modal accepting multiple
.torrentfiles and magnet/URL paste, with tags applied at add time and anAdd stoppedoption for import workflows (add stopped, recheck, then resume).
- Selected torrent panel with state, sizes, speeds, ratio, seeds/peers, ETA, added/completed dates, category, and save path.
- Quick tag editing with one-click toggles for existing tags.
- Tracker list with per-tracker status; click a tracker to expand its latest response message and peer counts, with force reannounce for the torrent or from any tracker row.
- File and peer lists for the selected torrent.
- Dark, terminal-inspired theme with configurable accent color and a compact table density option.
- Activity graph of upload/download speed history with the peak value labeled on the Y axis.
- Transfer totals, external IP, and free disk space in the sidebar.
- UI state (filters, search, sort, and appearance settings) persists across sessions in browser local storage.
- Modals close on backdrop click.
- Settings modal with common qBittorrent preferences, the full advanced preference list, and a revert-to-default-WebUI action.
- Login page using qBittorrent's WebUI credentials when authentication is required, with logout from the settings panel.
- Opt-in version update check (off by default — no GitHub request is made unless you enable it in settings): adds a sidebar version button that checks GitHub once per page load, highlights available updates, and opens a modal with the changelog, the release link, and the connected qBittorrent version.
- Works with both qBittorrent API generations (
torrents/start/torrents/stopwith fallback totorrents/resume/torrents/pause). - Preview mode with sample data whenever the qBittorrent API is unreachable, for local development.
- Release pipeline that tests, builds, generates a changelog, and uploads
qbitctl-<version>.zipplus a stable-URLqbitctl.zip.
Download the latest release and unzip it somewhere qBittorrent can read:
curl -fL -o qbitctl.zip \
https://github.com/mstraa/qbitctl-webui/releases/latest/download/qbitctl.zip
unzip -oq qbitctl.zipThen enable it by following qBittorrent's Alternate WebUI documentation, pointing the WebUI path at the extracted qbitctl/public folder.
The download URL always serves the newest version. To update, re-run the same two commands and reload the WebUI — the extracted path never changes, so qBittorrent needs no reconfiguration.
To revert, open qbitctl settings and use Revert to default qBittorrent WebUI, or disable Use alternative WebUI in qBittorrent.
- Node 24 (the version used by CI; Node 20.19+ or 22.13+ also work)
- Yarn 1.x (classic)
git clone https://github.com/mstraa/qbitctl-webui.git
cd qbitctl-webui
yarn install --frozen-lockfileyarn startThis starts the Vite dev server on http://localhost:3000. Without a reachable qBittorrent API the UI falls back to built-in preview data, so you can develop the interface without a running qBittorrent instance. To develop against a live qBittorrent, set QBIT_URL to its address and the dev server proxies /api calls to it:
QBIT_URL=http://localhost:8080 yarn startRun the tests with:
yarn testyarn build
yarn package:releaseyarn build outputs the WebUI to build/public. yarn package:release wraps it and creates:
dist/qbitctl-<version>.zip
dist/qbitctl.zip
The version defaults to the one in package.json; pass one explicitly with yarn package:release 1.3.0. Each zip contains a top-level folder (qbitctl-<version>/ or qbitctl/) with the built WebUI under public/. Point qBittorrent's alternative WebUI path at that public folder (see Install From A Release).
The GitHub Actions workflow in .github/workflows/release.yml runs tests, builds the WebUI, packages build/public, generates release notes from the commits since the previous version tag, and publishes both qbitctl-<version>.zip and the fixed-name qbitctl.zip on the release. Each release is marked latest, so releases/latest/download/qbitctl.zip always serves the newest version.
Create a release by pushing a version tag:
git tag v1.0.0
git push origin v1.0.0The workflow can also be run manually from GitHub Actions with an optional version input. Manual runs upload the zip as a workflow artifact. Tagged runs also publish it to the GitHub release.
qbitctl expects to be served by qBittorrent as an alternative WebUI. Live mode uses the same-origin qBittorrent API endpoints under /api/v2/*. When run locally with yarn start, it falls back to preview data when the qBittorrent API is not available.
The repository does not include personal IP addresses, tokens, qBittorrent credentials, or local configuration files. The external IP and free space shown in the sidebar come exclusively from your own qBittorrent API in live mode (no third-party IP services are contacted; preview mode shows a placeholder), and the optional version update check only contacts GitHub when explicitly enabled in settings.
Based on ntoporcov/qbittorrent-webui-react-boilerplate.



