A small desktop app for browsing a movie feed and streaming over BitTorrent — built with Tauri. Pick a quality, hit Stream now, and playback starts while the torrent downloads in the background.
Note: stream ships with no content and no feed. You must point it at your own source API (see Bring your own source). The default URL is a non-functional placeholder.
Frontend
- React 19 + TypeScript
- Vite 7 for dev server and bundling
- Vitest + Testing Library for component tests
Backend (Tauri / Rust)
- Tauri 2 — native shell, window, and IPC bridge
- librqbit — embedded BitTorrent engine with an HTTP API for range-based streaming
- axum + tokio — local HTTP server that streams torrent data to the video element
- reqwest — fetches the movie feed from your source API
The frontend calls Rust via Tauri commands (src/api.ts → src-tauri/src/commands.rs). The Rust engine resolves a magnet/torrent, exposes the selected file over a localhost stream URL, and the React Player plays it back as it buffers.
src/ React UI (Browse, Details, Player, Settings)
api.ts Typed wrappers over Tauri commands
views/ Screen components
src-tauri/src/
commands.rs Tauri command handlers (IPC surface)
engine.rs librqbit streaming/download engine
sources/ Feed source adapters (custom_json)
settings.rs Persisted source URL + download dir
- Node.js 18+ and npm
- Rust (stable toolchain)
- Tauri system dependencies for your OS — see the Tauri prerequisites guide
Install dependencies and produce a native, distributable bundle:
npm install
npm run tauri buildThis runs npm run build (TypeScript check + Vite production build) and then compiles the Rust binary, emitting platform installers/bundles (.app/.dmg, .deb/.AppImage, .msi/.exe) under:
src-tauri/target/release/bundle/
For a hot-reloading dev build:
npm install
npm run tauri devRun the frontend tests:
npm teststream has no built-in catalog. Open Settings in the app and set your source URL, or edit the persisted settings.json directly. The source is a JSON HTTP endpoint; two formats are accepted.
1. YTS-style list_movies.json — if the response contains data.movies[], it's parsed as a movie-list feed:
{
"data": {
"movie_count": 75665,
"limit": 20,
"page_number": 1,
"movies": [
{
"id": 1,
"title": "The Matrix",
"year": 1999,
"rating": 8.7,
"runtime": 136,
"genres": ["Action", "Sci-Fi"],
"large_cover_image": "https://.../cover.jpg",
"summary": "A computer hacker discovers...",
"torrents": [
{
"url": "https://.../the-matrix-720p.torrent",
"quality": "720p",
"type": "bluray",
"video_codec": "x264",
"bit_depth": "8",
"audio_channels": "2.0",
"seeds": 100,
"peers": 100,
"size": "703.69 MB",
"size_bytes": 737893000
}
]
}
]
}
}The app appends query parameters for paging, search, genre, and sort (e.g. ?page=2&query_term=matrix&genre=action&sort_by=...), matching the YTS list_movies API contract.
2. Native format — a flatter shape the app maps 1:1 to its feed model:
{
"items": [
{
"id": "matrix-1999",
"title": "The Matrix",
"year": 1999,
"poster": "https://.../cover.jpg",
"sources": [
{ "quality": "720p", "magnet": "magnet:?xt=urn:btih:..." }
]
}
],
"hasMore": true
}Whatever endpoint you configure must be reachable over HTTPS and return one of these shapes. You are responsible for the legality of the content your source exposes.
Released under the MIT License.