ArcDLP
ArcDLP Website
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
Download & Install
Download the latest release
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
No dependencies to install. yt-dlp and ffmpeg are bundled inside the app.
macOS
- Download the
.dmg file
- Open it and drag ArcDLP to your Applications folder
- Open ArcDLP
macOS will show a security warning the first time because the app is not
code-signed yet. This is normal.
To fix it:
- Click Done
- Open System Settings
- Go to Privacy & Security
- Scroll down and click Open Anyway next to ArcDLP
- Enter your password
You only need to do this once.
If macOS instead says ArcDLP “is damaged and can’t be opened”, open Terminal,
run this, then open ArcDLP again:
xattr -cr /Applications/ArcDLP.app
Windows
- Download and run the
.exe installer
- Click More info, then click Run anyway
- The installer will set up ArcDLP and create a shortcut automatically
ArcDLP installs per-user (no admin required) and can be uninstalled from
Settings > Apps.
Linux
- Download the
.AppImage file
- Make it executable: right-click → Properties → Permissions → check Allow
executing file as program
- Double-click to run
Features
- Single video downloads - Fetch video info, preview metadata, choose
quality (4K/2K/1080p/720p/480p/360p/240p), and download as MP4 or extract
audio as MP3. Fetch multiple URLs back-to-back without waiting - each result
appears in a side panel for quick review and queueing
- Video codec selection - Choose Auto, H.264, VP9, or AV1 in Settings.
Applied as a preference rather than a hard filter, so a video that doesn’t
offer the chosen codec still downloads using the best available one
- Playlist support - Paste a playlist URL, select which items to download,
pick a format, and queue them all at once
- Instagram saved collections - Paste a saved collection URL, the app scrapes
all post links from the collection page, and queues them for download
- Download queue - Sequential processing with per-item progress, retry,
cancel, and skip. One failure never stops the rest
- YouTube sign-in - Access age-restricted, private, and members-only content
through a built-in browser login window. Credentials go directly to Google
- Instagram sign-in - Access your private saved collections through a
built-in browser login window. Credentials go directly to Instagram
- Download history - Quick access to previously fetched videos with cached
metadata
- Multi-site compatibility - Works with any site yt-dlp supports. Format
detection adapts automatically to different streaming approaches across sites
- Update notifications - The app checks for new releases on startup and lets
you know when an update is available
- Light and dark mode - Follows your system preference. macOS vibrancy
supported
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/ArcDLP by default (changeable in
Settings)
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
Player, and every video editor. YouTube only serves H.264 up to 1080p, so 4K
and 2K downloads fall back to another codec
- 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
This is a preference, not a hard requirement. If a site doesn’t offer the chosen
codec, the download still runs with the best available format and the log says
which qualities were affected. H.264 and AV1 are saved as MP4, VP9 as WebM.
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
window using your Instagram session
- It scrolls through the page, collecting all
<a> tags with /p/ and
/reel/ href patterns
- Found posts appear in a playlist-style picker where you can select/deselect
items
- Click Add Selected to Queue - each post is downloaded individually via
yt-dlp with your Instagram cookies
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
always know what’s happening.
- Explicit actions only. No auto-fetching, no auto-retrying. Every action
traces to a button click.
- Let yt-dlp do the work. Don’t reimplement what yt-dlp already handles. The
app is a GUI wrapper, not a competing tool.
- Multi-site compatibility. Never assume YouTube-specific behavior unless
explicitly scoped. Format detection, error handling, and UI labels should work
for any site yt-dlp supports.
Getting Started
- Fork and clone the repo
npm install (downloads yt-dlp + ffmpeg automatically) - See details below
for Windows and Linux install
npm run dev to 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
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-json to get video metadata and available formats
- Result appears in a side panel. User picks a quality preset or audio
extraction
- Click “Add to Queue” - the download is queued, the result is removed from the
panel, and the next fetched item loads automatically
- yt-dlp handles the actual download with
--progress-template for structured
progress output
- Completed files are saved to the configured download folder
Multiple URLs can be fetched back-to-back. Each fetch runs sequentially (to
avoid rate limiting from video sites) and results accumulate in the side panel.
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 (<a href="/p/...">)
and (<a href="/reel/...">) 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
merging
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
rendered yet (completed in v1.2.3)
- File size estimates - Show approximate size on quality presets when
available
- Download complete notification - System notification when the queue
finishes (only if window is not focused)
- Playlist fetch cancellation - Currently can’t cancel a playlist fetch
mid-way through
- Verbose log toggle - Clean messages by default, raw yt-dlp output when
debugging
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-metadata for tagging files
- SponsorBlock integration -
--sponsorblock-remove, --sponsorblock-mark
to skip or mark sponsored segments
- Additional audio formats - AAC, FLAC, WAV, Opus extraction (currently MP3
only)
- Format filtering - Expose yt-dlp’s format selection syntax for advanced
users
- Download archive -
--download-archive to skip already-downloaded videos
- Rate limiting -
--limit-rate for bandwidth control
- Proxy support -
--proxy for users behind restrictive networks
- Custom output templates -
--output template configuration in settings
- Chapter splitting -
--split-chapters to save individual chapters as
separate files
App-Level Features
- Keyboard shortcuts - Quick access to common actions
- More site-specific auth - Expand the cookie login flow to more sites
beyond YouTube and Instagram
- Playlist detection for more sites - Currently conservative (YouTube,
SoundCloud, and Instagram saved collections)
- DOM virtualization for large playlists - Currently renders all items,
works fine under ~1000
Known Cleanup Items
video:fetch IPC returns the full raw JSON (50-200KB) even in production -
should be dev-only
- Queue
_items array has no upper bound - consider a cap or auto-clear
- Playlist checkbox uses inline
onchange handler - 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.
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
MIT
Credits
- yt-dlp - The engine that does all the
heavy lifting
- Electron - Desktop app framework
- ffmpeg - Audio/video processing (bundled via
ffmpeg-static)
- electron-icon-builder - Made icon with Canva and exported the icon files via electron-icon-builder
评论