Skip to content

chukjosh/NewPipeWeb

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NewPipeWeb

A full-featured, self-hosted frontend for YouTube, SoundCloud, PeerTube and more, built on top of NewPipeExtractor.

Licensed under GPL-3.0 — the same license as NewPipeExtractor. No Google account required. No ads. No tracking.


Table of Contents

  1. Features
  2. Tech Stack
  3. Prerequisites
  4. Quick Start
  5. Running in Development
  6. Running with Docker
  7. Desktop App (Tauri)
  8. User Guide
  9. Settings Reference
  10. SponsorBlock
  11. API Reference
  12. Project Structure
  13. Troubleshooting

Features

Feature Description
🔍 Search Search YouTube, SoundCloud, PeerTube without an account
📺 Watch Play videos with quality selector (144p–2160p)
🎵 Audio only Switch to background audio mode — saves bandwidth
🖼️ Picture in Picture Float video in a small window while browsing
💬 Comments Read comments without signing in
🔤 Subtitles Select subtitle language; auto-generated subtitles supported
⏩ Resume Automatically resumes where you left off
📡 Feed Latest videos from subscribed channels
🔔 Subscriptions Subscribe to channels — stored locally, no Google account
🔖 Watchlist Save videos to watch later
📚 Playlists Create and manage local playlists
🕐 History Full watch history with resume positions
⬇️ Downloads Download video or audio to your server
⏭️ SponsorBlock Opt-in automatic sponsor segment skipping
🌙 Dark / Light Toggle between dark and light theme
🐳 Docker One command to run the full stack
🖥️ Desktop Wrap as a native desktop app via Tauri

Supported Services

Service Search Watch Channel Trending Comments
YouTube
SoundCloud
PeerTube
Bandcamp
media.ccc.de
Odysee

Switch services using the dropdown in the search bar. The service selector only shows services relevant to the current context (e.g. the trending tab only shows services with a trending feed).


Tech Stack

Layer Technology
Extraction engine NewPipeExtractor (Java/Kotlin)
Backend API Ktor (Kotlin)
Database SQLite via Exposed ORM
Frontend React + Vite + Tailwind CSS
State management Zustand
Data fetching TanStack Query
Desktop wrapper Tauri 2
Container Docker + Docker Compose

Dependencies

Backend (Kotlin / JVM)

Build tool & Language:

Component Version Purpose
Kotlin 2.0.0 JVM language
JDK 22 Java runtime
Gradle 8.14 Build system

Core libraries:

Library Version Purpose
Ktor Server Core 2.3.12 HTTP server framework
Ktor Server Netty 2.3.12 Async network engine
Ktor Content Negotiation 2.3.12 JSON/serialization middleware
Ktor CORS 2.3.12 Cross-origin request handling
Ktor Call Logging 2.3.12 Request/response logging
Ktor Status Pages 2.3.12 Error handling
Ktor Client CIO 2.3.12 HTTP client for file streaming

Extraction & Parsing:

Library Version Purpose
NewPipeExtractor 0.26.0 (JitPack) YouTube/SoundCloud/PeerTube extractor
Kotlinx Serialization 1.6.3 JSON serialization

Database:

Library Version Purpose
Exposed Core 0.50.1 ORM framework
Exposed DAO 0.50.1 Data access objects
Exposed JDBC 0.50.1 JDBC driver integration
Exposed Java Time 0.50.1 DateTime support
SQLite JDBC 3.45.3.0 SQLite driver

Async & Utilities:

Library Version Purpose
Kotlinx Coroutines 1.8.1 Async/await support
Logback 1.5.6 Logging implementation
dotenv-kotlin 6.4.1 Environment variable loading

Testing:

Library Version Purpose
Ktor Server Tests 2.3.12 Integration testing
Kotlin Test 2.0.0 Unit testing framework

Frontend (Node.js / TypeScript)

Build & Runtime:

Tool Version Purpose
Node.js 24 LTS JavaScript runtime
TypeScript 5.4.5 Type-safe JavaScript
Vite 5.3.1 Dev server & build tool
React Router 6.23.1 Client-side routing

UI & Styling:

Library Version Purpose
React 18.3.1 Component framework
React DOM 18.3.1 React rendering engine
Tailwind CSS 3.4.4 Utility-first CSS
PostCSS 8.4.38 CSS preprocessor
Autoprefixer 10.4.19 CSS vendor prefixes
clsx 2.1.1 Conditional CSS classes
Lucide React 0.383.0 Icon library

State & Data:

Library Version Purpose
TanStack Query 5.40.0 Server state management
Zustand 4.5.2 Client state (preferences, UI)
Axios 1.7.2 HTTP client

Media:

Library Version Purpose
React Player 2.16.0 Video/audio playback

Dev Tools:

Tool Version Purpose
Vite React Plugin 4.3.1 Vite React JSX support
ESLint Latest Code linting

Desktop (Tauri 2 / Rust)

Frontend wrapper:

Component Version Purpose
Tauri 2.0.0 Desktop app framework
Tauri CLI 2.0.0 Build & dev tool
Tauri API 2.0.0 Rust/JavaScript bridge
Tauri Shell Plugin 2.0.0 Shell command execution

Serialization:

Library Version Purpose
serde 1.0 Rust serialization
serde_json 1.0 JSON support

Rust toolchain:

Tool Version Purpose
Rust Latest (via rustup) Systems language
Cargo Latest (via rustup) Rust package manager

DevOps & Containerization

Tool Version Purpose
Docker Latest Container runtime
Docker Compose Latest Multi-container orchestration
nginx Latest Reverse proxy & static server
Alpine Linux 3.x Lightweight base image

Prerequisites

For the web app (backend + frontend)

Tool Version Download
JDK 21 or 25 adoptium.net
Node.js 24 LTS nodejs.org
Git Any git-scm.com

For Docker (optional but recommended)

Tool Download
Docker Desktop docker.com/products/docker-desktop

For the desktop app (optional)

Tool Download
Rust toolchain rustup.rs
C++ build tools Windows: Visual C++ Build Tools
Xcode CLT macOS: xcode-select --install
WebKit dev libs Linux: see Desktop App section

Quick Start

# 1. Clone or unzip the project
cd my-newpipe-web

# 2. Start everything with Docker
docker compose up --build

# 3. Open in browser
open http://localhost:3000

That's it. The backend runs on port 8080, frontend on port 3000.


Running in Development

Running without Docker gives you hot-reload on both frontend and backend.

1. Start the backend

cd backend

# First run: Gradle will download all dependencies including NewPipeExtractor
./gradlew run

# On Windows:
gradlew.bat run

The backend starts on http://localhost:8080.

On first run Gradle downloads dependencies — this takes 1–3 minutes. Subsequent starts are much faster.

2. Start the frontend

Open a new terminal:

cd frontend
npm install      # first run only
npm run dev

The frontend starts on http://localhost:5173.

The Vite dev server proxies all /api requests to the Ktor backend automatically, so you don't need to configure CORS or URLs manually.

3. Open the app

Navigate to http://localhost:5173 in your browser.


Running with Docker

Docker runs the full stack (backend + frontend + nginx) in containers.

# Build and start
docker compose up --build

# Run in background
docker compose up --build -d

# Stop
docker compose down

# View logs
docker compose logs -f backend
docker compose logs -f frontend

Ports

Service Port
Frontend (nginx) http://localhost:3000
Backend (Ktor) http://localhost:8080

Persistent data

Docker mounts two local directories as volumes:

Directory Contents
./data/ SQLite database (history, playlists, subscriptions, etc.)
./downloads/ Downloaded video and audio files

These persist across container restarts. Back them up to keep your data.


Desktop App (Tauri)

The desktop app wraps the web frontend in a native window using Tauri. It requires the Ktor backend to be running separately.

Install Rust

# Install rustup (the Rust toolchain manager)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Restart your terminal, then verify:
rustc --version
cargo --version

Install system dependencies

Windows: Install Visual C++ Build Tools and select "Desktop development with C++".

macOS:

xcode-select --install

Linux (Ubuntu/Debian):

sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev \
  libayatana-appindicator3-dev librsvg2-dev build-essential

Run the desktop app

# Make sure the backend is already running:
cd backend && ./gradlew run

# In a new terminal, start the frontend dev server:
cd frontend && npm run dev

# In another terminal, start the desktop app:
cd desktop
npm install
npm run dev

A native window opens pointing at the frontend. Any changes to the frontend hot-reload in the window automatically.

Build a distributable

cd desktop
npm run build

Output is in desktop/src-tauri/target/release/bundle/.

  • Windows: .msi installer
  • macOS: .dmg
  • Linux: .AppImage or .deb

User Guide

Browsing & Searching

Home page shows trending videos from YouTube.

Search — type in the search bar at the top and press Enter or click the 🔍 icon. Results come from YouTube (and other supported services if the URL is recognized).

Recent searches are saved locally and shown as you type.

Watching a Video

Click any video card to open the watch page.

Quality selector — below the player toolbar, click any resolution badge to switch. Your preferred quality is applied automatically (set in Settings).

Playback speed — use the browser's native controls (right-click the video). Your default speed is set in Settings.

Resume — if you've watched part of a video before, it automatically picks up from where you left off.

Subtitles

  1. Click the CC button in the player toolbar to enable subtitles.
  2. Language buttons appear below the quality selector.
  3. Click a language to switch.
  4. Set your preferred default language in Settings → Player → Preferred subtitle language.

Auto-generated subtitles are labeled (auto).

Picture in Picture

Click the PiP button in the player toolbar. The video pops out into a small floating window managed by your browser. You can browse other pages while the video keeps playing. Click the X on the PiP window or press PiP again to return to full mode.

PiP requires a browser that supports the Picture-in-Picture API (Chrome, Edge, Safari, Firefox 116+).

Background Audio Mode

Click the Audio only button to switch the player to an audio-only stream. This is useful for music or podcasts — it uses significantly less data and CPU than video streams.

Click the button again to switch back to video.

Subscriptions

On any Channel page, click Subscribe. The subscription is saved locally in the database — no Google account needed.

The Feed page shows the latest videos from all your subscribed channels, sorted by upload date.

The Subscriptions page lists all channels you've subscribed to. Click a channel name to go to its page, or click Unsubscribe to remove it.

Watchlist

On any video's watch page, click the Save (bookmark) button to add it to your watchlist. Click again to remove it.

View your watchlist from the left sidebar.

Playlists

Creating a playlist:

  1. Go to Library in the sidebar.
  2. Click New Playlist.
  3. Enter a name and optional description.
  4. Click Create.

Adding a video to a playlist:

  1. Open the video's watch page.
  2. Click the Playlist button.
  3. Select an existing playlist or create a new one on the spot.
  4. A checkmark confirms the video was added.

Viewing a playlist:

  1. Go to Library.
  2. Click on any playlist card.
  3. Videos are listed in order. Click any to watch.

Watch History

The History page shows all videos you've watched, most recent first. Each entry stores your watch position so you can resume later.

  • Click any entry to resume watching.
  • Click the trash icon to remove a single entry.
  • Click Clear All to wipe the full history.
  • You can also clear history from Settings → Privacy.

Downloads

On any video's watch page, click Download. The download starts immediately in the background on the server.

Go to the Downloads page to:

  • See download progress (with a progress bar for active downloads)
  • Download the completed file to your device (click the ↓ icon)
  • Delete downloads

Downloaded files are stored in the ./downloads/ directory on the server.

Note: The download uses the currently selected stream URL. If you want audio only, enable Background Audio Mode first, then click Download.

Comments

On the watch page, click Show Comments to load and display the comments section. Click again to collapse it.

Pinned comments are marked 📌. Comments hearted by the creator are marked ❤️.


Settings Reference

Open Settings from the left sidebar (gear icon at the bottom).

Appearance

Setting Description
Theme Toggle between dark mode (default) and light mode

Player

Setting Default Description
Preferred quality 720p Automatically selects this quality when opening a video
Default playback speed 1x Videos start at this speed
Show subtitles by default Off Auto-enable CC when available
Preferred subtitle language en ISO 639-1 code for your preferred subtitle language

SponsorBlock

Setting Default Description
Enable SponsorBlock Off Master toggle — must be enabled for any skipping to happen
Sponsor segments Paid promotions integrated into the video
Self-promotion Creator's own unpaid promotions
Interaction reminders Like/subscribe/comment calls to action
Intro / title card Opening animation or title card
Outro / credits Closing credits or endscreen
Preview of content Teaser for what's coming up
Off-topic (music) Non-music sections in music videos
Filler / tangent Filler content or tangents unrelated to the topic

See SponsorBlock categories for detailed descriptions.

Privacy & Data

Action Description
Clear history Deletes all watch history from the database
Clear recent searches Clears the local search history shown in the search bar

SponsorBlock

SponsorBlock is a community-driven project that crowdsources timestamps for skippable segments in YouTube videos.

How it works in NewPipe Web

  1. Go to Settings and enable SponsorBlock.
  2. Choose which segment categories you want to skip.
  3. When you watch a video, the app fetches segment timestamps from sponsor.ajay.app using only the video ID.
  4. When your playback position enters a segment, it automatically skips to the end of that segment.
  5. A brief toast notification shows what was skipped.
  6. A counter in the player toolbar shows how many segments were skipped.

Privacy

  • Only the video ID is sent to the SponsorBlock API.
  • Your watch history, identity, and IP address are not associated with any user account in SponsorBlock.
  • SponsorBlock is disabled by default. You must explicitly enable it in Settings.
  • If the SponsorBlock API is unreachable, video playback continues normally.

Contributing

If you notice incorrect segments or want to contribute timestamps, install the SponsorBlock browser extension or use the Android app.


API Reference

All endpoints are served by the Ktor backend on port 8080. In Docker, the frontend nginx config proxies /api/* to the backend.

YouTube / Extraction endpoints

Method Path Description
GET /search?q={query} Search for videos
GET /video/{id} Get video metadata
GET /stream/{id} Get playable stream URLs + subtitles
GET /channel/{id} Get channel info + recent videos
GET /trending Get trending videos
GET /comments/{videoId} Get video comments

History

Method Path Description
GET /history Get all watch history (newest first)
POST /history Add or update a history entry
DELETE /history Clear all history
DELETE /history/{id} Remove a single entry

POST /history body:

{
  "videoId": "dQw4w9WgXcQ",
  "title": "Video title",
  "uploader": "Channel name",
  "thumbnailUrl": "https://...",
  "duration": 212,
  "watchedSeconds": 95
}

Watchlist

Method Path Description
GET /watchlist Get watchlist
POST /watchlist Add a video
DELETE /watchlist/{id} Remove a video

Playlists

Method Path Description
GET /playlists List all playlists
POST /playlists Create a playlist
GET /playlists/{id} Get playlist with all videos
DELETE /playlists/{id} Delete a playlist
POST /playlists/{id}/videos Add a video to a playlist
DELETE /playlists/{id}/videos/{videoItemId} Remove a video

Subscriptions & Feed

Method Path Description
GET /subscriptions List all subscriptions
POST /subscriptions Subscribe to a channel
DELETE /subscriptions/{id} Unsubscribe
GET /feed Latest videos from subscribed channels

Downloads

Method Path Description
GET /downloads List all downloads
POST /downloads Start a new download
GET /downloads/{id} Get download status
DELETE /downloads/{id} Delete download record + file
GET /downloads/{id}/file Download the completed file

Project Structure

my-newpipe-web/
│
├── backend/                         Kotlin + Ktor API server
│   ├── build.gradle.kts             Dependencies (NewPipeExtractor, Exposed, etc.)
│   ├── Dockerfile
│   └── src/main/kotlin/com/newpipeweb/
│       ├── Application.kt           Entry point
│       ├── NewPipeDownloader.kt     HTTP adapter for NewPipeExtractor
│       ├── plugins/                 Ktor plugin configs (CORS, routing, etc.)
│       ├── routes/                  API route handlers
│       ├── services/
│       │   └── YouTubeService.kt    All NewPipeExtractor calls
│       ├── database/
│       │   ├── tables/              SQLite table definitions
│       │   └── repositories/       Database CRUD operations
│       └── models/                  Serializable data classes
│
├── frontend/                        React + Vite + Tailwind
│   ├── src/
│   │   ├── App.tsx                  Router + layout
│   │   ├── main.tsx                 Entry point
│   │   ├── api/
│   │   │   ├── client.ts            All backend API calls
│   │   │   └── sponsorblock.ts      SponsorBlock API client
│   │   ├── components/
│   │   │   ├── layout/              Navbar, Sidebar
│   │   │   ├── video/               VideoCard, VideoGrid
│   │   │   ├── playlist/            AddToPlaylistModal
│   │   │   └── common/              LoadingSpinner, ErrorMessage, EmptyState
│   │   ├── hooks/
│   │   │   ├── index.ts             All TanStack Query hooks
│   │   │   └── useSponsorBlock.ts   SponsorBlock segment hook
│   │   ├── pages/                   One file per route
│   │   ├── store/
│   │   │   └── useAppStore.ts       Zustand global state + user preferences
│   │   └── types/
│   │       └── index.ts             TypeScript interfaces
│   ├── Dockerfile
│   └── nginx.conf                   Serves frontend + proxies /api to backend
│
├── desktop/                         Tauri 2 desktop wrapper
│   └── src-tauri/
│       ├── tauri.conf.json          Window config, points at frontend
│       ├── Cargo.toml               Rust dependencies
│       └── src/main.rs              Minimal Tauri entry point
│
├── data/                            SQLite database (auto-created, git-ignored)
├── downloads/                       Downloaded files (auto-created, git-ignored)
├── docker-compose.yml
└── README.md

Troubleshooting

Backend won't start

Could not find com.github.TeamNewPipe:NewPipeExtractor

  • Make sure JitPack is in your repositories in build.gradle.kts
  • Run ./gradlew dependencies to force a dependency refresh
  • Check your internet connection — JitPack needs to build the library on first fetch

Port 8080 already in use

  • Something else is running on 8080
  • Change the port in Application.kt: port = 8081
  • Update vite.config.ts proxy target to match

Videos won't play

Stream URLs expire — NewPipeExtractor stream URLs are valid for roughly 6 hours. If you leave a video paused for a long time and come back, you may need to refresh the page to get fresh stream URLs.

No playable stream found — YouTube occasionally changes its internal API. Check the NewPipeExtractor releases for a newer version and update build.gradle.kts.

SponsorBlock not working

  • Make sure it's enabled in Settings (it's off by default)
  • Check at least one segment category is selected
  • Open browser DevTools → Network tab and look for requests to sponsor.ajay.app
  • If requests return 404, the video has no community-submitted segments yet

Docker issues

Backend container exits immediately

docker compose logs backend

Look for the error. Common cause: JDK version mismatch in Dockerfile. Change eclipse-temurin:21-jre-alpine to eclipse-temurin:25-jre-alpine if needed.

bind: address already in use Change the host port in docker-compose.yml:

ports:
  - "8081:8080"   # host:container

Desktop app (Tauri)

cargo not found — Install Rust: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

WebKit2GTK not found (Linux) — Install system dependencies:

sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev librsvg2-dev

White screen in desktop window — Make sure both the backend (./gradlew run) and the frontend dev server (npm run dev) are running before launching Tauri.

About

NewPipe for the web. A full-featured, self-hosted YouTube frontend built on top of NewPipeExtractor. Watch YouTube without ads, tracking, or a Google account. Self-hosted, open source, GPL-3.0.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors