EasyX-Downloader

EasyX-Downloader

Docker app from Raccommode's Repository

Overview

EasyX Downloader is a private, self-hosted, plugin-first media acquisition manager. It organizes performers, sources, download queues, schedules, exact SHA-256 deduplication, and completed media while leaving website-specific discovery and downloading to trusted plugins.

EasyX Downloader

EasyX Downloader icon

EasyX Downloader is a private, self-hosted, plugin-first media acquisition manager. The core organizes people, sources, media candidates, downloads, deduplication, scheduling, and storage. It does not know how to download from any website until you install a plugin.

[!IMPORTANT] EasyX is for adults who download content they are legally allowed to access and retain. It is not a DRM bypass, paywall bypass, or authorization bypass. Plugins are trusted server-side code: review them before installation and follow every source's terms and applicable law.

What the MVP includes

  • English-only responsive web interface
  • Performer discovery across enabled identity plugins
  • Dedicated performer manager for manual creation, identity refresh, images, URL/plugin ownership, and explicit deletion choices
  • Source discovery with separate provenance and per-URL scraper selection
  • Explicit opt-in scraping and per-source sync schedules
  • Plugin-declared URL compatibility and polling recommendations, including second-level live checks
  • Manual or automatic download queues
  • Exact SHA-256 and perceptual image deduplication across sources for the same performer
  • Plugin-provided identity keys and measured pixel quality so the best known variant wins
  • Oldest reliable publication date reconciliation across duplicates, written to the database, filesystem time, and supported image/video metadata
  • Performer / source-domain / filename media organization
  • Immediate media-folder creation when a performer is added, before the first download
  • SQLite metadata store with no external database dependency
  • A public TypeScript plugin SDK
  • Stash shipped as a separate, optional first-party plugin
  • No-key discovery plugins for Boobpedia, Babepedia, IAFD, EuroPornstar, and Wikidata
  • Optional JavLibrary performer-directory discovery through an administrator-provided FlareSolverr
  • An optional FreeOnes public-page scraper with isolated failure reporting
  • First-party Web Media, RSS/Atom, Reddit RSS, configurable Nitter RSS, Facebook, Fansly, Instagram, ManyVids, OnlyFans, Patreon, TikTok, Tumblr, X, Pornhub, XVideos, YouTube, Twitch Live, and Chaturbate Live scrapers
  • Bundled gallery-dl, yt-dlp, OF-Scraper, FFmpeg, and ExifTool runtime for extraction, live recording, visual matching, and media dates
  • One simple Config view for every installed plugin, with visual connection status and uninstall; extractor internals stay automatic
  • Stable URLs for every workspace page, including browser history and direct reload support
  • Single-container Docker deployment

The Stash plugin searches performers already present in your Stash instance, imports known profile links, and triggers a selective Stash scan after a completed download. Stash itself is not part of the core. Every provider is a separate plugin and the core still starts without any provider installed.

Quick start

git clone https://github.com/raccommode/EasyX-Downloader.git
cd EasyX-Downloader
docker compose up -d

Open http://localhost:3210, accept the responsible-use notice, then open Plugins. Installing a plugin activates it immediately. Plugins with required credentials collect their settings before the atomic install-and-activate step; removing a capability is a single Uninstall action. Then use Discover. Boobpedia and Wikidata use public APIs. Babepedia, IAFD, EuroPornstar, and FreeOnes need no key but parse public pages and can become unavailable if a site changes or blocks automated access.

When several providers return the same normalized performer name, EasyX shows one grouped result. Adding it stores every selected provider reference, merges aliases and known profile URLs, and discovers sources through each provider. A failed provider is reported beside the search without discarding healthy results.

Discovered and manually added URLs always remain Reference only by default. Installing a plugin never assigns it globally and never changes another performer. In Performers, explicitly choose a scraper for one URL, then use its separate Scrape now action. Only enable scheduling or automatic downloads for that specific URL when you deliberately want them. The provider that found the URL remains visible and is not overwritten by the scraper selection.

Scraper plugins declare the URL patterns they support. EasyX only offers compatible plugins beside each performer URL, applies the plugin's recommended interval, and lets the administrator override it per URL. Periodic plugins can use minutes or hours; future live-aware plugins can declare a five-second minimum and use the separate live default in Settings.

Plugin Transport API key Provides
Boobpedia Public MediaWiki API No Performer identity, aliases, image, official/social profiles
Babepedia Public HTML with browser-compatible TLS No Performer identity, aliases, and public social profiles
IAFD Public HTML with browser-compatible TLS No Performer identity, aliases, headshots, and public profile links
EuroPornstar Public HTML No European performer identity, profile, and preview image
JavLibrary Public directory through FlareSolverr FlareSolverr URL required JAV performer identity and star-page reference
Wikidata Official Wikibase API No Structured identity, aliases, image, official/social profiles
FreeOnes Public HTML scraper No Performer identity, image, FreeOnes profile sections
Stash Your Stash GraphQL API Optional Local performer identity, known URLs, post-download scan
Web Media Public page or direct file No Open Graph media, images, videos, and linked media files
RSS / Atom Media Public RSS or Atom No Media enclosures and embedded entry media
Reddit RSS Public Reddit RSS No Public subreddit or user media exposed in RSS
Nitter RSS for X Administrator-provided Nitter instance No Public X profile media exposed by Nitter RSS
Facebook gallery-dl Optional cookies Public page/profile photos, plus content visible to the supplied session
Fansly gallery-dl Authorization token required Media already visible to the authenticated account; no subscription or purchase bypass
Instagram gallery-dl Session cookies required Posts and reels visible to the authenticated account
ManyVids Public storefront + yt-dlp No; optional cookies Public creator storefront preview clips; no purchase bypass
OnlyFans OF-Scraper Imported auth.json session required Individually queueable media already authorized for the account; no paywall or authorization bypass
Patreon gallery-dl Session cookies required Post media visible to the authenticated member account
TikTok gallery-dl Session cookies required Profile posts visible through the authenticated browser session
Tumblr Official Tumblr API via gallery-dl Application key and secret required Blog post images and videos; optional user access tokens
X (Twitter) gallery-dl Session cookies required Profile photos and videos visible to the authenticated account
Pornhub yt-dlp No; optional cookies Public profile, model, pornstar, or channel video listings and selected downloads
Chaturbate Live yt-dlp + FFmpeg No; optional cookies Public room status checks and user-selected live recording
YouTube yt-dlp No; optional cookies Public channel, handle, playlist, or video listings and selected downloads
Twitch Live yt-dlp + FFmpeg No; optional cookies Public channel status checks and user-selected live recording

Docker mounts:

  • ./data:/data — database and application state
  • ./media:/media — completed downloads
  • ./plugins-external:/plugins:ro — external plugins

PUID and PGID control the non-root identity used after volume permissions are prepared. They default to 1000:1000. For a standard Unraid installation, add these container variables:

PUID=99
PGID=100

Map a persistent appdata directory to /data, your library root to /media, and optionally a read-only plugin directory to /plugins. The startup script repairs ownership of the small database directory before dropping privileges, which avoids SQLite ERR_SQLITE_ERROR: unable to open database file on Unraid bind mounts.

Plugins never ask for a cookie-file path. When a signed-in session is required, open the plugin setup and either paste the Cookie header from your own browser or import a Netscape cookies.txt export. EasyX converts it when necessary, stores it under the persistent /data/sessions directory with private file permissions, and masks it in the API. OnlyFans instead accepts an OF-Scraper auth.json or compatible OnlyFans Cookie Helper JSON export, validates its required fields, and creates the internal OF-Scraper profile automatically. Public sources work without an account whenever the extractor supports that. Fansly still accepts its authorization token, while Tumblr uses credentials from your own Tumblr application. EasyX does not request or store account passwords.

JavLibrary enforces a browser challenge, so its plugin refuses to install until a FlareSolverr URL is configured. With the supplied Compose file, start the optional resolver and use http://flaresolverr:8191 in the plugin setup:

docker compose --profile javlibrary up -d

On Unraid, run FlareSolverr on a Docker network shared with EasyX and enter the resolver's container URL. EasyX verifies that the challenge is actually cleared when you use Test connection.

If Stash runs in another Compose project, attach both containers to a shared Docker network or use a reachable LAN URL. Mount the same media directory into Stash and set Path visible to Stash to the path used inside its container.

The public container is published automatically on every push:

docker pull ghcr.io/raccommode/easyx-downloader:latest

Every push produces an immutable sha-<short commit> tag and a branch/tag-name tag. Pushes to main also update latest.

Development

Requirements: Node.js 22.5+ and npm 10+.

npm install
npm run dev
  • Web UI: http://localhost:5173
  • API: http://localhost:3210/api

Run all checks with:

npm run check

To build the container from your working tree instead of pulling GitHub Packages:

docker build -t easyx-downloader:local .

Plugin development

Read Plugin author guide and HTTP API. A minimal, inert example is available in examples/plugins/http-feed.

External plugins are directories containing an index.mjs or index.js default export. Put them under plugins-external/ for local Compose use. EasyX discovers code on disk, but the administrator must still install it in the UI; installation also activates it.

Privacy and security

EasyX is designed for a private LAN or a properly authenticated reverse proxy. It does not include user accounts in this MVP. Do not expose port 3210 directly to the public internet. Plugin settings, including API keys, are stored in the local SQLite database; protect the data volume and backups.

See SECURITY.md for the threat model and reporting process.

Roadmap

  • Signed plugin registry and permission review
  • Sandboxed plugin workers
  • Perceptual video fingerprints in addition to exact hashes and image fingerprints
  • Retention policy execution and recoverable trash
  • Multi-user authentication and audit logs
  • Bandwidth windows and richer scheduler policies

License

MIT. Third-party plugins remain under their own licenses and are solely responsible for the services they integrate.

Install EasyX-Downloader on Unraid in a few clicks.

Find EasyX-Downloader in Community Apps on your Unraid server, review the template, and click Install. Unraid handles the Docker app or plugin setup from the published template.

Open the Apps tab on your Unraid server Search Community Apps for EasyX-Downloader Review the template variables and paths Click Install

Requirements

This Unraid template runs EasyX as nobody:users (UID 99, GID 100) so it can write to standard Unraid appdata paths without running as root. EasyX does not include downloader plugins by default. Install only plugins you trust and use them only for content you are legally allowed to access and retain. EasyX has no user accounts in the current release; keep port 3210 on a private LAN or behind an authenticated reverse proxy and do not expose it directly to the internet. Plugin settings and API keys are stored in the Data path, so protect that directory and its backups. If Stash runs in another container, give both containers a shared Docker network or use a reachable LAN URL, mount the same Media host path into Stash, and configure EasyX with the matching path visible inside Stash.

Related apps

Details

Repository
ghcr.io/raccommode/easyx-downloader:latest
Last Updated2026-08-24
First Seen2026-08-24

Runtime arguments

Web UI
http://[IP]:[PORT:3210]
Network
bridge
Shell
sh
Privileged
false
Extra Params
--user=99:100

Template configuration

Web UI PortPorttcp

EasyX web interface and API port. Keep this accessible only on a trusted LAN or through an authenticated reverse proxy. Container port: 3210.

Target
3210
Default
3210
Value
3210
DataPathrw

Stores the SQLite database, application state, plugin configuration, API keys, and schedules. Back up and protect this path.

Target
/data
Default
/mnt/user/appdata/easyx-downloader
Value
/mnt/user/appdata/easyx-downloader
MediaPathrw

Stores completed downloads. Mount this same host directory into Stash if you want EasyX to trigger Stash scans.

Target
/media
Default
/mnt/user/EasyX
Value
/mnt/user/EasyX
External PluginsPathro

Optional directory containing trusted external plugin folders. Each plugin must expose an index.mjs or index.js default export, then be installed and enabled in the EasyX web interface.

Target
/plugins
Default
/mnt/user/appdata/easyx-downloader/plugins
Value
/mnt/user/appdata/easyx-downloader/plugins
TimezoneVariable

Timezone used by the container and scheduled jobs, for example America/Toronto.

Target
TZ
Default
America/Toronto
Value
America/Toronto