JellyTube is a local, frontend-only Svelte application that turns selected Jellyfin libraries into a YouTube-style browsing and watching experience. It is designed for Jellyfin servers that already host downloaded YouTube archives, movies, episodic shows, and music videos.
These screenshots live in screenshots/ and are embedded here so users can preview JellyTube directly from the README.
Home feed |
Movies |
Show guide |
Music videos |
Subscriptions |
Search |
Watch page |
Mobile watch |
The README preview uses a curated screenshot set from the browser smoke workflow. The same workflow can generate additional route, history, autoplay, and failure-state screenshots locally.
To regenerate the screenshots, run the app and connect the smoke script to a Jellyfin test server:
npm run dev
BIDI_PORT=9226 \
JELLYTUBE_APP_URL=http://127.0.0.1:5173/ \
JELLYTUBE_SERVER_URL=http://your-jellyfin.example \
JELLYTUBE_USERNAME=your-admin-user \
JELLYTUBE_PASSWORD=your-password \
SCREENSHOT_DIR=./screenshots \
node scripts/bidi-smoke.mjs
The smoke script requires a browser exposing a WebDriver BiDi endpoint on BIDI_PORT and writes PNG files to SCREENSHOT_DIR.
From the JellyTube directory on Linux, macOS, or WSL, run:
./scripts/quick-setup.sh
From the JellyTube directory on Windows, run:
npm run setup:windows
The setup script installs dependencies, builds the production frontend, and starts JellyTube detached from the terminal.
Defaults:
http://localhost:41730.0.0.0.jellytube/.jellytube/jellytube.pid.jellytube/jellytube.logUse a different port or host by setting environment variables:
JELLYTUBE_PORT=8088 JELLYTUBE_HOST=127.0.0.1 ./scripts/quick-setup.sh
On Windows:
$env:JELLYTUBE_PORT = "8088"
$env:JELLYTUBE_HOST = "127.0.0.1"
npm run setup:windows
Stop the detached server with:
./scripts/stop.sh
On Windows:
npm run stop:windows
npm ci
npm run build
npm run serve
npm run serve serves the built dist/ folder with SPA routing fallback and static asset caching. It does not run the Vite development server.
npm install
npm run dev
Open the local Vite URL, sign in with Jellyfin credentials, and select the Jellyfin libraries that should appear in JellyTube.
Useful development checks:
npm run check
npm run test:unit
npm test
The Home route is optimized for return visits. Continue watching appears first when Jellyfin has resume data, followed by recommendations, latest uploads sorted by content/release date where possible, and replay picks based on play count.
Movies are intentionally separated from normal channel uploads. Movie cards use poster-style presentation, movie metadata points back to the Movies route, and watch-page recommendations stay movie-only.
Music Videos groups compatible items into artist/channel mixes. Opening a mix starts a queue-backed watch flow with autoplay-next behavior and the queue panel visible beside the player.
Subscriptions is a directory, not a subscription-management feature. It derives shows and channels from already-loaded Jellyfin items, supports filtering, and avoids eager full-series API expansion until a channel/show is opened.
Non-episodic channels show a latest-by-release-date grid plus replay picks. Episodic shows use season-aware guides with episode ordering and actions to play the latest episode or the selected season.
Search works across selected libraries and ranks likely show/episode matches above unrelated title matches. Results preserve visual identity, so movies, episodes, music videos, and standard videos remain distinguishable.
The Watch page prepares a direct stream when the browser can play it and falls back to Jellyfin HLS when needed. It reports progress to Jellyfin, resumes from saved playback position, persists volume/mute state, supports seeking and fullscreen, and can continue through episode shelves or mix queues.
The Libraries route lets server owners add or remove supported Jellyfin libraries after onboarding without signing out.
The production server reads these optional environment variables:
| Variable | Default | Description |
|---|---|---|
JELLYTUBE_HOST |
0.0.0.0 |
Host/IP address for the production server to bind. |
JELLYTUBE_PORT |
4173 |
Port for the production server. |
JELLYTUBE_DIST |
dist |
Directory containing the built frontend. |
JELLYTUBE_RUNTIME_DIR |
.jellytube |
Runtime directory used by quick setup. |
JELLYTUBE_PID_FILE |
.jellytube/jellytube.pid |
PID file for the detached server. |
JELLYTUBE_LOG_FILE |
.jellytube/jellytube.log |
Log file for the detached server. |
JellyTube is a frontend-only app. It does not proxy Jellyfin credentials or media through a backend service. Credentials and session data are stored in the user's browser local storage, and media/API calls go directly from the browser to the configured Jellyfin server.
Because JellyTube runs in the browser, the Jellyfin server must be reachable from that browser and configured to allow the browser requests needed by your deployment.