ArcDLP
Open-source desktop video downloader powered by yt-dlp. Paste a URL, pick a quality, download.
Supports YouTube, Vimeo, Twitter/X, SoundCloud, Instagram, and thousands of other sites.
Everything runs locally on your machine - no cloud, no accounts, no tracking.
Download & Install
Go to the Releases page, scroll down to Assets, and click the file for your system:
- macOS:
ArcDLP-x.x.x.dmg - Windows:
ArcDLP-Setup-x.x.x.exe - Linux:
ArcDLP-x.x.x.AppImage
macOS
- Download the
.dmgfile - Open it and drag ArcDLP to your Applications folder
- Open ArcDLP
To fix it:
- Click Done
- Open System Settings
- Go to Privacy & Security
- Scroll down and click Open Anyway next to ArcDLP
- Enter your password
Windows
- Download and run the
.exeinstaller - Click More info, then click Run anyway
- The installer will set up ArcDLP and create a shortcut automatically
Linux
- Download the
.AppImagefile - Make it executable: right-click → Properties → Permissions → check **Allow
- Double-click to run
Features
- Single video downloads - Fetch video info, preview metadata, choose
- Video codec selection - Choose Auto, H.264, VP9, or AV1 in Settings.
- Playlist support - Paste a playlist URL, select which items to download,
- Instagram saved collections - Paste a saved collection URL, the app scrapes
- Download queue - Sequential processing with per-item progress, retry,
- YouTube sign-in - Access age-restricted, private, and members-only content
- Instagram sign-in - Access your private saved collections through a
- Download history - Quick access to previously fetched videos with cached
- Multi-site compatibility - Works with any site yt-dlp supports. Format
- Update notifications - The app checks for new releases on startup and lets
- Light and dark mode - Follows your system preference. macOS vibrancy
Usage
- Paste a video or playlist URL and click Fetch
- Pick a quality (or choose MP3 for audio extraction)
- Click Add to Queue
- Downloads are saved to
~/Downloads/ArcDLPby default (changeable in
You can paste and fetch additional URLs while reviewing results. Each fetched video appears in a side panel - click any item to review it, pick a quality, and add it to the queue. Adding a video to the queue automatically loads the next one.
For playlists, you can select/deselect individual items and choose a format for the whole batch before queueing.
To access private or age-restricted YouTube videos, sign in via **Settings > YouTube Account**. Your credentials go directly to Google through their standard login page.
Video Codec
Settings > Video controls which video codec is preferred for downloads:
- Auto (default) - Whatever yt-dlp ranks highest for the requested quality
- H.264 - The most compatible option. Plays in QuickTime, Windows Media
- VP9 - Smaller files than H.264 at the same quality. Saved as WebM
- AV1 - The smallest files, but needs a reasonably modern player or editor
Instagram Saved Collections
yt-dlp supports downloading individual Instagram posts and reels, but it has no extractor for saved collections. ArcDLP bridges this gap with a built-in scraper.
- Sign in to Instagram via Settings > Instagram Account
- Paste a saved collection URL (e.g.
https://www.instagram.com/username/saved/collection-name/12345/)
- Click Fetch - the app opens the collection page in a hidden browser
/reel/ href patterns
- Found posts appear in a playlist-style picker where you can select/deselect
- Click Add Selected to Queue - each post is downloaded individually via
The scraper stops after 5 consecutive scrolls with no new posts, or after a 3-minute timeout (partial results are returned if any were found). Large collections may be rate-limited by Instagram.
Support the Project
If ArcDLP is useful to you, consider supporting development:
For Developers
Everything below is for people who want to build from source, modify the app, or contribute.
Contributing
Contributions are welcome. The codebase is intentionally simple - no frameworks, no build tools, vanilla JS throughout.
Before making changes, read through the code and match existing patterns. A few principles the project follows:
- Keep it simple. If something can be done in 30 lines, don't use a library.
- Resilience first. One failure should never kill the queue. Users should
- Explicit actions only. No auto-fetching, no auto-retrying. Every action
- Let yt-dlp do the work. Don't reimplement what yt-dlp already handles. The
- Multi-site compatibility. Never assume YouTube-specific behavior unless
Getting Started
- Fork and clone the repo
npm install(downloads yt-dlp + ffmpeg automatically) - See details below
npm run devto launch with DevTools - See more details below- Make your changes, test across a few different sites
- Open a PR with a clear description of what changed and why
Build from Source
git clone https://github.com/archisvaze/arcdlp.git
cd arcdlp
npm install
Cross-platform builds
Both ffmpeg-static and the yt-dlp postinstall script download platform-specific
binaries during npm install. On macOS, this works automatically, no setup needed.
If you're building for a different architecture (e.g. building the Linux x64
AppImage from an ARM machine), set these environment variables before
npm install to ensure the correct binaries are downloaded:
Windows (x64):
$env:npm_config_platform = "win32" $env:npm_config_arch = "x64" rm -r -Force node_modules npm install
Linux (x64):
export npm_config_platform=linux export npm_config_arch=x64 rm -rf node_modules bin npm install
Only one binary per platform is downloaded per install. If you need to switch
target architectures, delete node_modules and bin and run npm install
again with the new env vars.
Development
npm run dev # macOS / Linux
npm run dev:win # Windows
This launches the app with DevTools enabled and verbose logging.
Production Builds
npm run build:mac # macOS - produces .dmg and .zip
npm run build:win # Windows - produces NSIS installer
npm run build:linux # Linux - produces AppImage
npm run build:all # All platforms
Both yt-dlp and ffmpeg binaries are bundled into the built app via
extraResources in package.json.
Project Structure
arcdlp/
├── src/
│ ├── main/
│ │ ├── main.js # Electron main process, IPC, window, history
│ │ ├── preload.js # Context bridge (window.api)
│ │ ├── ytdlp.js # yt-dlp integration: spawn, parse, download
│ │ ├── queue.js # Sequential download queue with per-item state
│ │ ├── cookies.js # YouTube + Instagram cookie auth
│ │ ├── scraper.js # Instagram collection scraper (BrowserWindow)
│ │ ├── updater.js # Update checker via GitHub Releases API
│ │ └── utils.js # Dev mode flag, logging helpers
│ └── renderer/
│ ├── index.html # UI structure
│ ├── renderer.js # UI logic, state, rendering
│ └── index.css # All styles
├── scripts/
│ ├── postinstall.js # Downloads yt-dlp binary on npm install
│ └── fix-ffmpeg-win.js # Renames ffmpeg for Windows builds
├── bin/ # yt-dlp binary (auto-populated by postinstall)
├── build/ # App icons (icon.icns, icon.ico, icon.png)
├── package.json
├── LICENSE
└── README.md
How It Works
- User pastes a URL and clicks Fetch
- App spawns
yt-dlp --dump-jsonto get video metadata and available formats - Result appears in a side panel. User picks a quality preset or audio
- Click "Add to Queue" - the download is queued, the result is removed from the
- yt-dlp handles the actual download with
--progress-templatefor structured
- Completed files are saved to the configured download folder
For playlists, the app uses --flat-playlist --dump-json to stream items one at
a time, then queues selected items for download.
For Instagram saved collections, the app opens the collection page in a hidden
BrowserWindow, scrolls through it collecting anchor tags ()
and () via executeJavaScript, then presents the scraped
URLs in the playlist picker UI. Each post is then downloaded individually by
yt-dlp using the Instagram session cookies.
Dependencies
Only two runtime dependencies:
- electron-store - Persistent settings and history
- ffmpeg-static - Bundled ffmpeg binary for audio extraction and format
Dev dependencies: electron, electron-builder.
yt-dlp handles all downloading, format selection, and ffmpeg orchestration internally. The app is a GUI wrapper around it.
Roadmap
ArcDLP covers the core download workflow, but yt-dlp has a huge feature set that could be surfaced in the GUI. Here's what's planned and where contributors can help.
Quality of Life
- ~~Thumbnails in playlist items - The data is already fetched, just not
- File size estimates - Show approximate size on quality presets when
- Download complete notification - System notification when the queue
- Playlist fetch cancellation - Currently can't cancel a playlist fetch
- Verbose log toggle - Clean messages by default, raw yt-dlp output when
Advanced yt-dlp Features
yt-dlp supports a lot more than basic downloading. These features would make great contributions:
- Subtitle downloads -
--write-subs,--sub-langs, language selection UI - Embed metadata -
--embed-thumbnail,--embed-metadatafor tagging files - SponsorBlock integration -
--sponsorblock-remove,--sponsorblock-mark
- Additional audio formats - AAC, FLAC, WAV, Opus extraction (currently MP3
- Format filtering - Expose yt-dlp's format selection syntax for advanced
- Download archive -
--download-archiveto skip already-downloaded videos - Rate limiting -
--limit-ratefor bandwidth control - Proxy support -
--proxyfor users behind restrictive networks - Custom output templates -
--outputtemplate configuration in settings - Chapter splitting -
--split-chaptersto save individual chapters as
App-Level Features
- Keyboard shortcuts - Quick access to common actions
- More site-specific auth - Expand the cookie login flow to more sites
- Playlist detection for more sites - Currently conservative (YouTube,
- DOM virtualization for large playlists - Currently renders all items,
Known Cleanup Items
video:fetchIPC returns the full raw JSON (50-200KB) even in production -
- Queue
_itemsarray has no upper bound - consider a cap or auto-clear - Playlist checkbox uses inline
onchangehandler - could use event delegation - Log type detection is greedy (
msg.includes('complete')matches "incomplete")
Code signing policy
Free code signing provided by SignPath.io, certificate by SignPath Foundation. Only Windows installers built by GitHub Actions from this repository are signed. Signed builds start with the first release after the project is approved.
- Committers and reviewers: Archis Vaze
- Approvers: Archis Vaze
Privacy
ArcDLP has no accounts, analytics or telemetry. It only connects to the sites you download from, the GitHub releases API for the update check, and GitHub when you update yt-dlp from Settings. Full policy: arcdlp.archisvaze.com/privacy
License
Credits
- yt-dlp - The engine that does all the
- electron-icon-builder - Made icon with Canva and exported the icon files via electron-icon-builder