DevToolsmith

cURL to JavaScript Converter

Convert curl commands to JavaScript using the Fetch API or axios. JSON bodies become objects, -F uploads become FormData, and -m becomes an abort timeout. The code runs in modern browsers and in Node.js 18 and later.

Runs 100% in your browser — nothing is uploaded

curl command
Tip: drop a file here236 chars · 236 bytes · 4 lines
JavaScript · fetch (browser and Node.js 18+)
410 chars · 410 bytes · 20 lines
Parsed request

POST https://api.example.com/v1/orders?notify=true

  • Authorization: Bearer YOUR_API_TOKEN
  • Content-Type: application/json
  • Body: JSON
Notes
  • fetch (browser and Node.js 18+) re-serializes the JSON body, so the bytes differ from curl’s: curl sends {"customer": "cus_123", "items": [{"sku": "TSHIRT-M", "qty": 2}], "gift": false}, this code sends {"customer":"cus_123","items":[{"sku":"TSHIRT-M","qty":2}],"gift":false}.
  • That only matters if the server checks a signature or hash of the body. If it does, send the original text as a string instead.

Example

curl
curl -X POST https://api.example.com/v1/messages \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"to": "+15551234567", "text": "Hello"}' \
  -m 15
JavaScript (fetch)
const response = await fetch('https://api.example.com/v1/messages', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer YOUR_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    to: '+15551234567',
    text: 'Hello',
  }),
  signal: AbortSignal.timeout(15000),
});
const text = await response.text();
console.log(text);
Node.js (axios)
import axios from 'axios';

const response = await axios.post('https://api.example.com/v1/messages', {
  to: '+15551234567',
  text: 'Hello',
}, {
  headers: {
    Authorization: 'Bearer YOUR_TOKEN',
  },
  timeout: 15000,
});
console.log(response.data);

curl options in fetch and axios

curlfetchaxios
-X POSTmethod: 'POST'axios.post(url, data, config)
-Hheaders: {…}headers: {…}
-d JSONbody: JSON.stringify(obj)pass the object as data
-d a=1&b=2body: new URLSearchParams(…)new URLSearchParams(…)
-Fbody: formDataformData as data
-u user:passAuthorization: 'Basic ' + btoa(…)auth: { username, password }
-m 15signal: AbortSignal.timeout(15000)timeout: 15000
-kNot possiblehttpsAgent with rejectUnauthorized: false (Node.js)
-x proxyNot in browsers; NODE_USE_ENV_PROXY=1 in recent Node.jsproxy: { host, port } (Node.js)
-LDefault (redirect: 'follow')Default in Node.js

Handling the response

fetch with error handling
const response = await fetch(url, options);
if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}
const data = await response.json();

Using TypeScript? Paste a sample response into JSON to TypeScript or JSON to Zod to get types for data.

Frequently asked questions

Should I use fetch or axios?

fetch is built into browsers, Node.js 18+, Deno and Bun, so it needs no dependency. axios adds conveniences: it serialises objects to JSON automatically, rejects the promise on 4xx and 5xx responses, supports a timeout option and request interceptors, and in Node.js it can skip TLS verification or use a proxy. Both produce the same request.

Why doesn’t fetch throw on a 404 or 500?

fetch only rejects on network errors. An HTTP error status is still a successful response, so check response.ok (true for 200–299) or response.status before reading the body. axios throws an error with error.response set for non-2xx statuses.

The request works in curl but fails in the browser. Why?

Usually CORS. curl doesn’t enforce it, but a browser only lets your page read a response from another origin if the server sends Access-Control-Allow-Origin. Custom headers like Authorization also trigger a preflight OPTIONS request that the server must answer. Either enable CORS on the server or make the call from your backend. Browsers also refuse to set some headers, such as Cookie, Host and Referer, from fetch.

How do I upload a file with fetch?

Build a FormData, append fields and files, and pass it as the body. Don’t set Content-Type yourself: the browser adds multipart/form-data with the correct boundary. In the browser, take the file from an <input type="file">; in Node.js 20+, fs.openAsBlob(path) returns a Blob you can append, as the generated code does.

How is curl -m (timeout) converted?

For fetch, as signal: AbortSignal.timeout(ms), which aborts the request with a TimeoutError after that many milliseconds. For axios, as the timeout option in milliseconds. Neither has a timeout by default.