curlwtfcurlwtf

Converter

Convert curl to JavaScript fetch

Paste any curl command and get a ready-to-run JavaScript fetch() equivalent — headers, auth, JSON body, and all flags handled. Credentials are replaced with environment variable references automatically.

Open the converter →

Conversion examples

Common curl patterns and their exact fetch equivalents.

POST with JSON body (OpenAI)

curl
curl -X POST https://api.openai.com/v1/chat/completions \
  -H "Authorization: Bearer sk-proj-REDACTED" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o","messages":[{"role":"user","content":"Hello"}]}'
JavaScript fetch
const response = await fetch("https://api.openai.com/v1/chat/completions", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.OPENAI_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "gpt-4o",
    messages: [{ role: "user", content: "Hello" }],
  }),
});

const data = await response.json();
console.log(data);

GET with custom headers

curl
curl https://api.github.com/user \
  -H "Authorization: Bearer ghp_REDACTED" \
  -H "Accept: application/vnd.github+json"
JavaScript fetch
const response = await fetch("https://api.github.com/user", {
  headers: {
    "Authorization": `Bearer ${process.env.GITHUB_TOKEN}`,
    "Accept": "application/vnd.github+json",
  },
});

const user = await response.json();

Basic auth (-u flag)

curl
curl -u myuser:mypassword https://api.example.com/protected
JavaScript fetch
const credentials = btoa(`${process.env.API_USER}:${process.env.API_PASSWORD}`);

const response = await fetch("https://api.example.com/protected", {
  headers: {
    "Authorization": `Basic ${credentials}`,
  },
});

Form data (--data-urlencode)

curl
curl -X POST https://example.com/login \
  -d "username=alex" \
  -d "password=secret"
JavaScript fetch
const body = new URLSearchParams({
  username: process.env.USERNAME,
  password: process.env.PASSWORD,
});

const response = await fetch("https://example.com/login", {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: body.toString(),
});

How curl flags map to fetch options

Every curl flag has a direct equivalent in the fetch() API. Here is the complete mapping for the flags you'll encounter most often.

curl flagfetch equivalentnotes
-X METHODmethod: "METHOD"Defaults to GET; POST auto-set when body is present
-H "Key: Value"headers: { "Key": "Value" }Repeat for multiple headers
-d '{"json":true}'body: JSON.stringify({json: true})Also add Content-Type: application/json header
-d "field=value"body: new URLSearchParams({field: "value"})Sends application/x-www-form-urlencoded
-u user:passheaders: { Authorization: "Basic " + btoa("user:pass") }btoa() base64-encodes the credentials
-Lredirect: "follow""follow" is the fetch default — -L is implicit
--no-locationredirect: "manual"Prevents following redirects
-k / --insecureN/A in browserUse Node.js agent: { rejectUnauthorized: false }
-s / --silent(no equivalent)fetch never prints progress; -s is redundant
-o fileresponse.blob() or .arrayBuffer()Write to disk with fs.writeFile in Node.js

Error handling

curl returns a non-zero exit code on HTTP errors when you use -f (or --fail). The fetch() API does not throw on HTTP error status codes — a 404 or 500 still resolves successfully. You must check response.ok or response.status yourself.

// curl -f fails the script on 4xx/5xx
// fetch() does NOT throw on HTTP errors — check response.ok

const response = await fetch("https://api.example.com/data");

if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}

const data = await response.json();

fetch() only throws (rejects) on network failures like DNS errors, connection refused, or request aborted — not on HTTP 4xx or 5xx responses. Always add an if (!response.ok) guard for any production fetch call.

Frequently asked questions

How do I convert curl to fetch in JavaScript?

Paste your curl command at curlwtf.com and click the JavaScript tab. The converter handles every flag: -X sets the method, -H becomes a headers entry, -d is JSON.stringify'd into the body, and -u is base64-encoded as an Authorization: Basic header.

Does fetch follow redirects by default?

Yes. fetch() defaults to redirect: "follow", which is the same behaviour as curl -L. If your curl command doesn't use -L, the behaviour is the same — both curl and fetch follow 3xx redirects by default on most environments.

How do I send JSON with fetch?

Set body: JSON.stringify(yourObject) and add the header "Content-Type": "application/json". In curl this is -d '{"key":"value"}' -H "Content-Type: application/json". The fetch equivalent wraps the object in JSON.stringify and passes the same content-type header.

How do I add a bearer token to a fetch request?

Add "Authorization": `Bearer ${token}` to the headers object. This mirrors curl's -H "Authorization: Bearer TOKEN". Store the token in an environment variable — never hardcode credentials in client-side JavaScript.

What is the fetch equivalent of curl -u user:password?

curl -u uses HTTP Basic authentication. The fetch equivalent is headers: { "Authorization": "Basic " + btoa("user:password") }. btoa() base64-encodes the credentials exactly like curl's -u flag does internally.

Why does my converted fetch fail when curl works?

The most common causes are: (1) CORS — browsers enforce CORS but curl does not; (2) cookies — curl sends stored cookies, fetch needs credentials: "include"; (3) SSL — curl -k bypasses certificate errors, which requires a custom Node.js agent; (4) missing headers — some APIs require User-Agent or specific Accept headers that curl adds by default.

Other converters

→ curl to Python→ curl to Go