Skip to content
rewget GitHub

v1.0.1 · Linux + macOS

wget, but it works everywhere.

A drop-in wget replacement that automatically bypasses bot protection. When sites return 403, hand you a CAPTCHA, or just refuse to talk to a plain HTTP client, rewget retries with browser-grade fingerprints and, if it has to, a real headless browser.

$ brew install neul-labs/tap/rewget
$ rewget https://example.com/file.tar.gz
--2026-06-05 10:14:02--  https://example.com/file.tar.gz
file.tar.gz                100%[============>]   42.1M  18.6MB/s
[stage 1: wget] ok

3

stages of fallback: wget, fingerprint, browser

7 d

per-domain cache so the slow path runs once

42

tests covering every stage and edge case

How it works

A three-stage fallback that stays out of your way

Common case: wget. Blocked case: a browser fingerprint. Hard case: a real browser. The first stage that works wins, and rewget remembers which one it was.

stage 1 · wget

Plain, fast, zero overhead

Runs wget (or wget2) with your exact flags. If the site does not block, you get the same output you would have got from wget directly. No daemon spin-up, no browser cost.

stage 2 · impersonate

Browser TLS and HTTP/2

rewgetd retries through rquest with a Chrome, Firefox, Safari, or Edge fingerprint. Most fingerprint-based blocks fold here without ever touching a real browser.

stage 3 · js preflight

Headless Chromium, on demand

When the page genuinely needs JavaScript, chromiumoxide drives Chromium, solves the challenge, exports cookies and headers, and stage 2 retries with the session.

What you get

Pragmatic defaults, explicit flags

Compatible

Drop-in wget replacement

Same flags, same output, same scripts. Add an alias and your existing automation keeps running. Nothing to learn, nothing to rewrite.

Stage 2

Browser-grade TLS fingerprints

When stage 1 returns 403, rewgetd retries the same URL with a real Chrome, Firefox, Safari, or Edge TLS and HTTP/2 fingerprint via rquest.

Stage 3

Headless Chromium when needed

For pages that genuinely need JavaScript, stage 3 spins up Chromium via chromiumoxide, solves the challenge, exports the session, and resumes the download.

Caching

Per-domain cache, 7-day TTL

Once rewget learns which stage works for a host, subsequent downloads skip straight there. The common case stays fast; the slow path runs once.

Security

Ed25519-verified profiles

Browser fingerprint profiles are signed and verified on update. New Chrome and Firefox releases roll out through --rewget-update-profiles, not silent network fetches.

Architecture

Daemon-backed, CLI-first

rewgetd owns the browser pool and TLS sessions. The CLI stays a thin shim — fast to start, cheap to call from scripts and Makefiles.

Usage

The flags you will actually use

basic — auto fallback
$ rewget https://example.com/file.tar.gz
CI — fail fast
$ rewget --rewget-no-fallback https://example.com/file.tar.gz
force browser preflight
$ rewget --rewget-js https://example.com/
pick a profile
$ rewget --rewget-profile=firefox136 https://example.com/

Honest comparisons

Where rewget sits next to the classics

We are not trying to win an argument about wget vs curl. Both are good. rewget keeps the wget shape and fixes the cases where it falls down.

FAQ

Questions we get from people about to adopt this

+ Is rewget actually a drop-in replacement?

Yes. The CLI shim parses --rewget-* flags and forwards everything else unchanged to wget (or wget2 if you ask). If you alias wget=rewget, your existing scripts keep working. When a site does not block, you pay zero overhead — you get wget.

+ How does the three-stage fallback work?

Stage 1 runs plain wget. If it succeeds, that is the answer. If it fails on a fallback HTTP status (configurable via --rewget-fallback-codes), stage 2 retries through rquest using a browser TLS and HTTP/2 fingerprint. If stage 2 still fails, stage 3 launches headless Chromium to handle JavaScript challenges. The first stage that works wins.

+ Which browser profiles ship today?

Chrome 131 and 130, Firefox 136 and 133, Safari 18, and Edge 131. List them with --rewget-list-profiles. Update to the latest set with --rewget-update-profiles (Ed25519 verified).

+ Does it work on Windows?

The README lists Linux and macOS as the platform matrix today. We are not claiming Windows-native support until the release artifacts say so.

+ How do I install it?

Homebrew (brew install neul-labs/tap/rewget), npm (npm install -g rewget), PyPI (uv tool install rewget or pip install rewget), or cargo install rewget from source. There is also a one-line install script in the repo.

+ Can I disable the fallback for CI?

Use --rewget-no-fallback. The command fails fast on a block instead of escalating to stage 2 or 3. That is the right behaviour when you want CI to flag a regression instead of hiding it.

+ Does rewget bypass authenticated access control?

No. rewget handles fingerprint-based blocks and JavaScript challenges — the cases where a real browser would succeed and a plain HTTP client would not. If a site requires you to log in, rewget does not change that.

+ Is it really a single binary?

The CLI is. The daemon is a second binary that starts on demand and handles stage 2 and 3. Both ship from the same release; Homebrew, npm, PyPI, and the install script wire them together.

Tired of wget: ERROR 403?

Install rewget, alias wget=rewget, and forget about it. When a site lets you in, it is plain wget. When it does not, rewget is already retrying.