curl vs wget: What Is the Difference?
curl is an HTTP client for talking to services; wget is a downloader for retrieving files.
Side by side
| curl | wget | |
|---|---|---|
| Primary purpose | Transfer data to/from a URL | Download files from the web |
| Default output | stdout (pipeable) | A file on disk |
| HTTP methods | All of them (-X POST, PUT, DELETE) | GET and POST only |
| Custom headers | Yes (-H), core feature | Limited |
| Follows redirects | Only with -L | By default |
| Resume downloads | Yes (-C -), clumsier | Yes (-c), designed for it |
| Retry on failure | Manual (--retry) | Automatic by default |
| Recursive download | No | Yes (--mirror), can clone a site |
| Protocols | Dozens (HTTP, FTP, SMTP, IMAP, SCP…) | HTTP, HTTPS, FTP |
| Available as a library | Yes — libcurl, embedded everywhere | No |
Which one, when
Testing an API endpoint
Use curl
Methods, headers, request bodies and readable responses are exactly what curl is for. Output goes to stdout so it pipes straight into jq.
$ curl -sS -X POST -H "Content-Type: application/json" -d '{"name":"test"}' https://api.example.com/items | jq Downloading a large ISO
Use wget
Retries and resumes without you thinking about it. Run the same command again after a dropped connection and it continues from where it stopped.
$ wget -c https://example.com/ubuntu.iso Checking whether a site is up
Use curl
The --write-out flag extracts exactly the metadata you want — status code, timings — with no body noise. This one-liner powers countless health checks.
$ curl -sS -o /dev/null -w "%{http_code} %{time_total}s\n" https://example.com Saving documentation for offline reading
Use wget
Recursive fetching with link rewriting is a wget speciality that curl simply does not have.
$ wget --mirror --convert-links --wait=1 -np https://docs.example.com/ In a shell script that reacts to the response
Use curl
Printing to stdout makes it composable: pipe it, capture it in a variable, branch on the status code.
$ status=$(curl -sS -o /dev/null -w "%{http_code}" "$url") Gotchas worth knowing
- curl does not follow redirects unless you pass -L. Half the "curl returns nothing" reports are a 301 being shown faithfully.
- wget saves to a file and curl prints to the screen. Download a binary with curl and no -o and you get garbage in your terminal.
- Use curl -sS in scripts, not bare -s: the extra S keeps error messages while silencing the progress meter.
- Piping either tool straight into bash executes unreviewed remote code. Download, read, then run.
- On minimal container images neither may be installed. Alpine ships wget (a BusyBox version with fewer options); Debian slim images often have neither.
Frequently asked questions
Which one should I learn first?
curl, if you write software: APIs are everywhere and curl is how you poke them. wget takes ten minutes to learn when you need it.
Can curl download files like wget?
Yes: curl -LO url saves with the remote name. It just lacks the retry, resume-by-default and recursion that make wget a proper download manager.
Why does curl print HTML to my terminal?
Because stdout is its default output. Add -o file.html or -O to save it instead.
Is one more secure than the other?
Both verify TLS certificates by default. The insecure part is what you do next — piping downloaded scripts into a shell is the real risk, in either tool.
Full guides for both
Download files, test APIs, send POST requests with JSON, and inspect headers.
wgetDownload files and whole sites, resume interrupted transfers, and fetch in the background.
Other comparisons
Both copy files over SSH. rsync sends only what changed; scp sends everything, every time.
sed vs awksed edits lines; awk understands columns. Substitution is sed, computation is awk.
symbolic link vs hard linkA symlink stores a path and can break; a hard link is a second real name for the same file.
grep vs ripgrep (rg)grep is everywhere; ripgrep is dramatically faster on code and respects .gitignore by default.