Download Reddit images, GIFs & videos — entirely in your browser. No account. No tracking. No backend storing your data. Just a static page.
A complete, security-focused rewrite of the original RedditDownloader. It is a 100% static site (HTML + CSS + vanilla ES modules) that you can host on GitHub Pages or open from any static web server. All work — fetching listings, previewing media, packaging ZIPs — happens in the visitor's browser.
The original relied on a third-party CORS proxy (allOrigins) that could see all your
traffic. This rewrite removes that hard dependency and gives you explicit, switchable modes,
so you choose your own privacy/convenience trade-off — including an optional browser extension
that fetches everything from your own IP (the most reliable, proxy-free path).
- 🔗 Paste a post URL, a
redd.itshort link, areddit.com/media?url=…file link,r/subreddit,u/username, or just a subreddit name. - 🖼 Previews images, GIFs, native galleries, Reddit-hosted videos, and crossposts. Previews are lightweight thumbnails (a grid of hundreds stays smooth); downloads & ZIPs are always the full-quality originals.
- 🔀 Sort subreddits (hot / new / top / rising / …) with a time window.
- ✅ Select what you want, download individually or as a single ZIP.
- 🧩 Optional browser extension for proxy-free ZIP from your own IP (most reliable). Switchable proxy mode otherwise (see below). Your choice is remembered locally.
- 🕘 Link history — re-fetch past links in one click (newest = latest fetch).
- ⏭ Skip already-downloaded — remembers grabbed posts/images so big subreddits only fetch what's new (with a “count discarded as downloaded” toggle); a Skipped stat shows the rest.
- 🛠 Advanced settings — download rate-limit (delay), request timeout, max file size, max files per ZIP. All saved locally.
- 🛡 Hardened: strict Content-Security-Policy, locally-bundled libraries (no CDN), strict
host allowlisting, no
innerHTMLwith data, server-free. - 🧪 An extensive vitest suite covering the security-critical logic.
Browsers refuse to let JavaScript read the bytes of a cross-origin file unless that server
sends CORS headers. Reddit's image CDN (i.redd.it) does not. So images can be shown and
opened, but to bundle them into a ZIP the bytes must pass through something that adds CORS.
| Mode | Bulk ZIP | Who sees your traffic | Setup |
|---|---|---|---|
| Pulldit Extension | ✅ | Only you (your own IP, no relay) | One-time install — see extension/ |
| Direct (default) | ❌ | Only Reddit | None — most private |
| Your Cloudflare Worker | ✅ | Only you (your own proxy) | ~5 min, free — see worker/ |
| Public CORS proxy | ✅ | A third party relays it | None — most convenient |
In Direct mode you still get full previews and one-by-one downloads. Only the bulk ZIP requires reading raw bytes, which the browser blocks cross-origin.
Reddit also returns 403 Blocked to datacenter IPs — where every public proxy and even a
Cloudflare Worker live — so those are best-effort. The optional Pulldit Bridge
extension sidesteps both walls: its background worker is exempt from CORS and runs from your own
residential IP, so it fetches the listing JSON (no 403) and reads i.redd.it bytes (no CORS).
The website detects the extension automatically and unlocks an “Extension” mode — same page,
same UI, full proxy-free ZIP. It is locked to Reddit/imgur hosts and only serves the Pulldit page.
npm install
npm run serve # serves the repo root at http://localhost:8080Open http://localhost:8080. (A static server is required because ES modules don't load over
file:// — opening index.html by double-click won't work, just like the live site.)
This repo ships a workflow that does it automatically:
- Push to
main. - In Settings → Pages, set Source = GitHub Actions.
- The
deployworkflow stages the static files, packages the browser extension, and publishes everything. (It uploads onlyindex.html,styles.css,assets/,src/,vendor/, and the generatedpulldit-bridge.zip— nevernode_modules.)
A .nojekyll file is included so Pages serves the files as-is.
- No third-party code at runtime. JSZip and FileSaver are vendored into
vendor/(pinned, checksummed) and loaded from the same origin — no CDN supply-chain risk. - Strict CSP in
index.html:default-src 'none',script-src 'self',object-srcdisabled,base-uri/form-actionlocked, and aconnect-srcallowlist of exactly Reddit + the curated proxies. - Host allowlisting (
src/url-guard.js): every media URL is validated against an allowlist and rejected if it resolves to a private/reserved/loopback address — the client-side analogue of SSRF protection. The Cloudflare Worker enforces the same allowlist server-side and is not an open proxy. - Resource guards: per-request timeouts and a streamed hard size cap on every download.
- Safe DOM: all rendering uses
createElement+textContent; user/Reddit data is never injected as HTML. - Least-privilege extension: the optional browser extension requests
only
host_permissionsfor Reddit/imgur (no tabs, storage, or<all_urls>), enforces the same host allowlist in its background worker, and only serves requests from the Pulldit page — it is not an open proxy.
index.html # UI shell + strict CSP
styles.css # dark-first responsive styles
assets/logo.svg # logo / favicon
src/
config.js # allowlists, limits, proxy presets
url-guard.js # URL/host validation, IP checks, filename sanitizing
reddit.js # input parsing + listing normalization + thumbnails
proxy.js # proxy modes (direct/worker/public/extension) + hardened fetch
bridge-client.js # page-side client for the optional browser extension
filters.js # type/source filtering
stats.js # fetch/download statistics (cumulative)
history.js # activity log helpers
download.js # single + ZIP downloads (rate-limit, size/timeout caps)
app.js # UI controller (panels, link history, advanced settings, skip registry)
vendor/ # JSZip + FileSaver (pinned, local)
worker/ # optional self-hosted secure proxy (Cloudflare)
extension/ # optional MV3 browser extension (proxy-free ZIP via your own IP)
scripts/ # syntax-check, extension pack/bump, publish
test/ # vitest suites
.github/workflows/ # CI, Pages deploy, CodeQL, security scans
npm test # run the vitest suites
npm run check # syntax-check every shipped JS file
npm run build # check + test (the CI gate)
npm run pack:ext # package extension/ into pulldit-bridge.zip
npm run bump:ext # bump the extension's patch version (manifest = single source of truth)This software is provided “as is”, without warranty of any kind, and the authors accept no liability — see the MIT License.
You are solely responsible for what you download and how you use it. Respect copyright, the original creators, and Reddit's User Agreement. Download only content you have the right to. Do not use this tool for harassment, unauthorized redistribution, or any unlawful purpose.
Pulldit is an independent project and is not affiliated with, endorsed by, or sponsored by Reddit, Inc. “Reddit” is a trademark of Reddit, Inc.
MIT © Pulldit contributors