The Problem

Users who run a private torrent client often have to juggle a separate UI, a download client, and a media player. Switching between them adds latency, and exposing the torrent stream to browsers safely is non‑trivial. SeedBox Lite tries to collapse those pieces into a single web‑based streaming front‑end.

What This Does

The repo ships a React front‑end (client/) and an Express API (server/). The UI lives in client/src/App.jsx and renders AuthenticatedApp, which pulls data from the back‑end via the service layer (client/src/services/*.js). The API entry point is server/index.js; it registers routes, serves the video range requests, and handles authentication. Docker files (client/Dockerfile*, server/Dockerfile, docker‑compose.yml) let you spin up the whole stack with a single docker‑compose up.

Key files:

  • client/src/components/VideoPlayer.jsx – video element, time‑update handling.
  • client/src/services/progressService.js – stores per‑torrent progress (11 functions, used by 5 callers).
  • server/handlers/streamHandler.js – reads torrent files and serves HTTP range responses.
  • server/middleware/requestLimiter.js – throttles inbound requests (high branching density).

How It Is Wired

Execution begins in server/index.js (line 1). It creates an Express app, applies requestLimiter middleware, sets CORS ('*' with credentials – a high‑severity issue), and mounts route handlers. The most‑used handler universalTorrentResolver (line 515) calls loadTorrentFromId (3 calls) to locate a torrent, then streams via streamHandler. Only one outbound network call is made from the server (the torrent client library). File I/O occurs in streamHandler (reads torrent pieces) and progressService (reads/writes JSON progress files).

On the client side, the entry point client/src/App.jsx renders AuthenticatedApp. AuthenticatedApp immediately invokes fetchData (via useSmartPolling) which calls api.getTorrents. The API layer (client/src/services/api.js) forwards the request to the Express server. The UI components that consume the data are:

  • VideoPlayer.jsx – called by VideoPlayer (34 functions total, highest blast radius).
  • HomePage‑clean.jsx – loads recent torrents (loadRecentTorrents → getRecentTorrents) and adds new torrents (addTorrent).
  • TorrentPage.jsx – formats file size/speed (via formatFileSize, formatSpeed).

The internal call graph shows getAllProgress and fetchWithTimeout each invoked from 8 places, making them hot spots for change impact. No circular dependencies were detected, but client/src/components/TorrentList.jsx has an instability of 1 (imports three modules and is imported by none), indicating dead‑code risk.

How To Use It

# Clone the original repo
git clone https://github.com/moses-y/seedbox-lite.git
cd seedbox-lite

# Build and run with Docker (recommended)
docker-compose -f docker-compose.yml up -d

# If you prefer a local node environment
cd server && npm ci && npm start   # starts Express on default port
cd ../client && npm ci && npm run dev   # Vite dev server on port 5174

Configuration – copy the example files and fill in secrets:

cp .env.example .env               # server env
cp client/.env.example client/.env # client env

The server expects PORT, JWT_SECRET, and torrent client options (see ENVIRONMENT-CONFIG.md). The client reads REACT_APP_API_URL from its .env.

Real‑World Use

A home‑lab media server could run SeedBox Lite behind a reverse proxy. A user authenticates via the UI, selects a torrent from the “Recent” page, and the client streams directly from the server’s range endpoint (/stream/:infoHash). Progress is persisted in client/src/services/progressService.js, enabling resume across sessions.

Code Health & Issues

  • High – Secret file tracked: server/.env.production is committed despite .gitignore.
  • High – Vulnerable dependency: express@4.18.2 has CVE‑2024‑29041; upgrade required.
  • High – No test suite: 0 test files for 50 source files.
  • High – Missing lockfile: top‑level package.json lacks a lockfile; lockfiles exist only in sub‑folders.
  • High – No CI pipeline: no .github/workflows or similar.
  • High – Dockerfile not gated: client/Dockerfile builds without automated verification.
  • High – Committed .env files: .env.docker, .env.production, client/.env.production, server/.env.docker.
  • High – Wildcard CORS with credentials: Access-Control-Allow-Origin: * paired with credentials:true.
  • High – Runtime eval/exec in server/index.js.
  • Medium – High branching density in server/middleware/requestLimiter.js and server/handlers/streamHandler.js.
  • Medium – Deep nesting (max depth 10) in several component files.

Additional observations: the repository includes a licence (LICENSE) but lacks a CI configuration and has duplicated ecosystem config files (client/ecosystem-*.js), a DRY violation.

The Bottom Line

SeedBox Lite provides a functional end‑to‑end torrent streaming UI backed by an Express API and is container‑ready. However, the codebase suffers from serious security hygiene lapses (committed secrets, unsafe CORS, eval), outdated dependencies, and a complete lack of automated testing or CI. It is suitable for internal or experimental use where the team can remediate the highlighted issues before production deployment.