A modern, feature-rich web interface for qBittorrent client management, built with Vue 3, TypeScript, and Naive UI. Designed for both desktop and mobile devices with responsive design, virtual scrolling for high performance, and intelligent torrent filtering.
💡 If you find this project helpful, please consider giving it a ⭐ Star on GitHub! It helps more people discover this project and motivates me to keep improving it. Thank you! 🙏
- 🚀 Modern Tech Stack - Built with Vue 3 (Composition API), TypeScript, and Vite for blazing-fast development
- 📱 Responsive Design - Mobile-first UI that works seamlessly across desktop, tablet, and mobile devices
- ⚡ High Performance - Virtual scrolling for smooth handling of large torrent lists
- 🎨 Beautiful UI - Powered by Naive UI with a clean, modern interface
- 🌍 Internationalization - Multi-language support (English, 简体中文)
- 🔒 Secure Authentication - Login protection and session management
- 📊 Real-time Statistics - Live updates for torrent status, speed, and progress
- 🎯 Smart Filtering - Advanced torrent filtering by status, category, and tags
- 📁 File Management - Browse and manage torrent contents with ease
- 🔄 Drag & Drop - Intuitive torrent file and magnet link handling
- ⚙️ Comprehensive Settings - Full control over qBittorrent client settings
- 🐳 Docker Support - Easy deployment with Docker and Docker Compose
The easiest way to deploy qb-web is using the pre-built Docker image from Docker Hub.
Create a docker-compose.yml file:
services:
qb-web:
image: jianxcao/qbittorrent-web
container_name: qb-web
environment:
- BACKEND_URL=http://127.0.0.1:9091
ports:
- '7633:7633'
restart: unless-stoppedThen run:
docker-compose up -ddocker run -d \
--name qb-web \
-p 7633:7633 \
-e BACKEND_URL=http://127.0.0.1:9091 \
--restart unless-stopped \
jianxcao/qbittorrent-webIf you want to build the image yourself:
# Clone the repository
git clone https://github.com/jianxcao/qb-web.git
cd qb-web
# Build the image
docker build -t qb-web .
# Run the container
docker run -d \
--name qb-web \
-p 7633:7633 \
-e BACKEND_URL=http://your-qbittorrent:8080 \
--restart unless-stopped \
qb-web| Variable | Description | Default | Required |
|---|---|---|---|
BACKEND_URL |
qBittorrent WebUI API URL | http://localhost:9091 |
Yes |
PORT |
Port to run the web interface | 7633 |
No |
PUID |
User ID for file permissions | 0 |
No |
PGID |
Group ID for file permissions | 0 |
No |
UMASK |
File creation mask | 000 |
No |
Note: Make sure to replace
BACKEND_URLwith your actual qBittorrent WebUI address. If qBittorrent is running in another container, use the container name or service name (e.g.,http://qbittorrent:8080).
- Node.js >= 20.0.0
- pnpm >= 10.0.0
- qBittorrent with WebUI API enabled
git clone https://github.com/jianxcao/qb-web.git
cd qb-web
pnpm installCreate a .env.local file in the project root:
VITE_BASE_URL=/api/v2Start the development server with hot module replacement:
pnpm devThe application will be available at http://localhost:5173
Build the optimized production bundle:
pnpm buildThe build output will be in the dist/ directory.
Preview the production build locally:
pnpm previewRun TypeScript type checking:
pnpm checkRun ESLint to check and fix code style:
pnpm lintsrc/
├── api/ # API layer with qBittorrent WebUI integration
│ ├── modules/ # API modules (torrents, auth, rss, etc.)
│ ├── http.ts # HTTP client configuration
│ ├── types.ts # TypeScript type definitions
│ └── index.ts # API exports
├── components/ # Vue components
│ ├── CanvasList/ # High-performance virtual list component
│ ├── dialog/ # Dialog components (Settings, Add Torrent, etc.)
│ └── Settings/ # Settings panels
├── composables/ # Reusable composition functions
│ ├── useColumns.ts # Table column management
│ ├── useI18n.ts # Internationalization helper
│ └── useSelection.ts # Selection state management
├── store/ # Pinia stores
│ ├── torrent.ts # Torrent state management
│ ├── setting.ts # Application settings
│ └── session.ts # Session and authentication
├── views/ # Page-level components
│ ├── DashboardView.vue # Main torrent dashboard
│ ├── LoginView.vue # Login page
│ └── SettingsView.vue # Settings page
├── router/ # Vue Router configuration
├── i18n/ # Internationalization files
│ └── locales/ # Language files (en-US, zh-CN)
├── utils/ # Utility functions
└── styles/ # Global styles
| Category | Technology |
|---|---|
| Framework | Vue 3.5.27 (Composition API) |
| Language | TypeScript 5.8.3 |
| Build Tool | Vite 7.0.0 (with rolldown) |
| UI Library | Naive UI 2.43.2 |
| State Management | Pinia 3.0.4 |
| Routing | Vue Router 4.6.4 |
| HTTP Client | Axios 1.13.2 |
| Styling | UnoCSS 66.6.0 + Less 4.5.1 |
| I18n | Vue I18n 9.14.5 |
| Utilities | VueUse 13.9.0, Lodash-es 4.17.23 |
| Command | Description |
|---|---|
pnpm dev |
Start development server on port 5173 |
pnpm build |
Type-check and build for production |
pnpm build:prod |
Production build with environment setup |
pnpm check |
TypeScript type checking only |
pnpm preview |
Preview production build locally |
pnpm lint |
ESLint with auto-fix |
pnpm lint:fix |
Same as lint (auto-fix enabled) |
pnpm release |
GitHub Actions release |
pnpm release:check |
Environment validation |
This project follows these conventions:
- No semicolons (enforced by ESLint)
- Single quotes for strings
- 2 spaces for indentation
- 120 characters max line width
- Composition API for all Vue components
- TypeScript strict mode enabled
For more details, see AGENTS.md.
This project integrates with the qBittorrent WebUI API (v4.1+). For API documentation, see:
- Authentication - Login, logout, session management
- Torrents - List, add, delete, pause, resume, set properties
- Transfer - Global speed limits, connection settings
- Application - Preferences, default save path
- RSS - Feed management and rules
- Log - Main log and peer log
- Search - Plugin management and search operations
- Sync - Main data synchronization
Contributions are welcome! Here's how you can help:
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please ensure your code:
- Passes TypeScript type checking (
pnpm check) - Follows the code style guidelines (
pnpm lint) - Includes appropriate documentation
This project uses automated releases via GitHub Actions:
- Validate your environment:
pnpm release:check - Trigger the release workflow:
pnpm release - Semantic versioning and changelog generation are automated
This project is licensed under the MIT License.
Copyright (c) 2024-2026 Jianxiong Cao
Built with these excellent open-source projects:
- Vue 3 - Progressive JavaScript Framework
- Naive UI - Vue 3 Component Library
- Vite - Next Generation Frontend Tooling
- qBittorrent - Free BitTorrent Client
- TypeScript - Typed JavaScript
- Pinia - Vue Store
- UnoCSS - Instant On-demand Atomic CSS Engine
If you like this project, please give it a star! ⭐
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Made with ❤️ by Jianxiong Cao




