Yoink is a local desktop/web app for downloading high-fidelity video and audio from many platforms, powered exclusively by yt-dlp (with ffmpeg for merging high-quality streams).
It is split into two layers that communicate asynchronously:
- Frontend — React + TypeScript + Tailwind CSS (Vite). A reactive, dark-mode UI (English/Spanish) that shows previews, lets you pick the container/format, quality, subtitles and chapters, and reflects download progress in real time.
- Backend — Python + FastAPI (in
backend/). Wraps yt-dlp, manages the local filesystem, and invokes ffmpeg. Metadata is served over REST (POST /api/info); downloads stream live progress to the UI over a WebSocket (/api/ws/download).
- Analyze any URL (with a paste-from-clipboard button) → preview (title, thumbnail, duration) with the real available formats. ~1800 sites via yt-dlp.
- Search YouTube from the URL field — type a query instead of a URL and pick a result from the live dropdown (thumbnail, channel, views) to download it.
- Live downloads over WebSocket (percent / speed / ETA), with cancel and retry.
- Output formats, your choice:
- Video — MP4, MOV or MKV (ffmpeg merge), with optional embedded subtitles (language picker) and chapters/metadata.
- Audio — MP3, M4A, plus FLAC/WAV that are only offered when the source is genuinely lossless (no fake upscaling).
- Trim / clip — a scissors button to download only a time range (e.g.
0:30 → 2:10) of a video or audio. - Immersive / VR video — detects 180°/360° clips (SBS · TB · mono ·
fisheye / MKX / RF5.2) and tags the file so VR players (Quest / DeoVR /
Heresphere) show it in 3D: a projection name suffix plus injected Spherical
Video V2 metadata (
st3d/sv3d). Shown only when detected; you confirm or fix the layout, and it's remembered per channel. - Playlists — pick which items to download with checkboxes; they download sequentially with "X of N" progress (VR tagging applies to the whole batch).
- Download queue — paste many links to download one after another; the queue persists across restarts and resumes interrupted items.
- Audio auto-tagging — after an audio download, an inline card tags the file with real artist / album / title / year + cover art from Apple Music, Deezer or MusicBrainz (free, no account; pick one — or Automatic — in Settings); you review, edit or search before anything is written. Works per song and across whole playlists.
- SponsorBlock (optional, off by default) — strip or just mark sponsor / intro / outro segments on YouTube downloads, chosen in Settings.
- History & stats persisted locally (SQLite), with quality (resolution / bitrate), re-tagging, and cover art for tagged audio, open file / folder, and clear.
- Settings — download folder, default format/quality (up to 4K / best),
filename template, video codec & audio bitrate, bandwidth limit,
proxy (http/socks), language, and cookies (browser — with icons — or
cookies.txt). - Desktop notifications when a download finishes, taskbar/title progress, and keyboard shortcuts (Ctrl/Cmd+L focus URL, Ctrl/Cmd+, settings).
- English & Spanish UI (react-i18next), auto-detected from your system language and switchable in Settings.
- Update check against the latest GitHub release; Settings also shows the bundled yt-dlp version and whether a newer one is out.
- Self-contained desktop app (Tauri, Linux & Windows): bundles the backend and ffmpeg as a sidecar — no Python or ffmpeg install needed.
python scripts/setup.py # one-time: venv + backend deps + npm install
python scripts/dev.py # run backend (:8756) + frontend (:5173) togetherThen open http://localhost:5173. For development you need ffmpeg on your
PATH; the packaged desktop app bundles it. See CLAUDE.md for
per-layer commands.
python scripts/fetch_ffmpeg.py # once: download ffmpeg+ffprobe (LGPL) to bundle
python scripts/build_backend.py # bundle backend + ffmpeg as a PyInstaller sidecar
npm run tauri build # installers in src-tauri/target/release/bundlePrerequisites: Rust toolchain and, on Linux, webkit2gtk (4.1); on Windows,
WebView2 + MSVC build tools. Full flow in docs/releasing.md.
src/ # frontend (React + TS + Tailwind)
├── components/{layout,ui}
├── features/
│ ├── autotag/ # Apple Music tagging cards (single + playlist batch)
│ ├── downloader/ # URL input, preview, playlist, progress (main column)
│ ├── history/ # download history + stats (sidebar)
│ └── settings/ # settings modal (download dir, defaults, cookies, version)
├── lib/ # API client + download WebSocket
└── types/ # shared domain types (mirror the backend JSON contract)
backend/ # FastAPI + yt-dlp engine (see backend/README.md)
src-tauri/ # Tauri desktop shell
scripts/ # setup.py, dev.py, fetch_ffmpeg.py, build_backend.py
e2e/ # Playwright end-to-end tests
Issues and pull requests are welcome — see CONTRIBUTING.md
for how to propose a change and the checks to run.
Yoink's own source code is licensed under CC BY-NC-SA 4.0 (non-commercial,
share-alike) — see LICENSE. Bundled third-party components keep
their own licenses (ffmpeg = LGPL, yt-dlp = Unlicense); see
docs/THIRD_PARTY_LICENSES.md.
CLAUDE.md— high-level guide and conventionsCONTRIBUTING.md— how to contributedocs/— architecture, per-layer guides, the roadmap, the release process and third-party licenses
