A full-stack web app to download all media (photos, videos, GIFs) from any X (Twitter) profile as a ZIP file, powered by gallery-dl.
This project is intended for personal use only.
It is your responsibility to ensure that your use of this tool complies with X's Terms of Service and the applicable laws in your country. Do not use this tool to download, redistribute, or commercially exploit content that belongs to others without their explicit permission. I takes no responsibility for any misuse of this software.
- Filter by media type — download everything, photos only, videos only, or GIFs only
- Real-time progress — live progress bar, file count, download speed, and elapsed time via Server-Sent Events (SSE)
- Cancel anytime — stop the download mid-way with a single click
- ZIP download — all media packed and delivered as a
.zipfile - Desktop notifications — get notified when the download finishes
- Dark / Light theme — toggle between themes
- EN / FR language — switch between English and French
| Layer | Technology |
|---|---|
| Frontend | Next.js 14 · TypeScript · Tailwind |
| Backend | Python · Flask · gallery-dl |
| Protocol | REST + Server-Sent Events (SSE) |
- Node.js 18+
- Python 3.10+
- gallery-dl —
pip install gallery-dl - A valid X/Twitter cookies file (for authenticated downloads)
git clone https://github.com/your-username/x-media-downloader.git
cd x-media-downloaderOpen app.py and update the cookies path to match your system:
COOKIES_PATH = "C:/Users/YourName/path/to/cookies.txt"How to get your cookies file: Use a browser extension like Get cookies.txt LOCALLY while logged into X, then export as
cookies.txt.
pip install flask flask-cors gallery-dl
python app.pyThe API will run on http://127.0.0.1:5000.
npm install
npm run devOpen http://localhost:3000 in your browser.
x-media-downloader/
├── my-app/src/app
│ ├── page.tsx # Main UI component
│ └── api/
│ └── route.ts # Next.js API route (proxy to Flask)
├── twitter-media-python/
│ └── venv # Background image
│ └── app.py # Flask backend
└── README.md
Starts the media download for a given username.
Body:
{
"username": "elonmusk",
"mediaType": "all"
}mediaType accepts: "all" · "images" · "videos" · "gifs"
Response: application/zip file stream
SSE stream that emits real-time download progress.
Event payload:
{
"status": "downloading",
"message": "Downloading media…",
"count": 42,
"speed": 3.2,
"elapsed": 18
}status values: starting · downloading · zipping · done · error
Kills the running gallery-dl process for the given user.
| Variable | Location | Description | Default |
|---|---|---|---|
COOKIES_PATH |
app.py |
Path to your X/Twitter cookies file | (required) |
DOWNLOAD_DIR |
app.py |
Directory where media is saved | ~/Downloads/twitter_media |
DOWNLOAD_TIMEOUT |
app.py |
Max seconds before aborting gallery-dl | 300 |
X requires authentication to access media from most profiles. You must provide a valid cookies.txt file exported from a logged-in X session. The cookies are passed directly to gallery-dl and are never stored or transmitted elsewhere.
| Error | Cause | Fix |
|---|---|---|
Cannot reach x.com |
DNS/network issue or X is blocked in your region | Use a VPN or configure a proxy with --proxy |
Invalid or expired cookies |
Cookies have expired | Re-export your cookies from the browser |
User not found on X |
Username doesn't exist or profile is private | Check the username or use an account that follows the profile |
Rate limit reached |
Too many requests to X | Wait a few minutes before trying again |
Contributions are welcome! Please fork the repository and submit a pull request.
If this project helps you, consider starring the repository!