Convert curl to axios for Node.js
This curl to axios converter rewrites a curl command as a single axios({...}) call for Node.js. Instead of copying the full URL and a raw body string, it splits the request into the fields axios expects: url, params for the query string, headers, data, auth and timeout. The result uses ES module imports and top-level await.
Example: file upload with -F
For curl -F 'title=Q3 report' -F 'file=@report.pdf' -H 'X-Api-Key: YOUR_KEY' -L https://api.example.com/uploads you get:
import axios from 'axios';
import fs from 'node:fs';
import FormData from 'form-data';
const form = new FormData();
form.append('title', 'Q3 report');
form.append('file', fs.createReadStream('report.pdf'));
const response = await axios({
method: 'post',
url: 'https://api.example.com/uploads',
headers: {
...form.getHeaders(),
'X-Api-Key': 'YOUR_KEY',
},
data: form,
});The form-data package streams the file from disk, and form.getHeaders() supplies the multipart Content-Type with its boundary.
How curl maps to the axios config
- Query string:
?page=2&sort=nameis moved into aparamsobject, which axios encodes for you. When a key repeats (?tag=a&tag=b), the full URL is kept and noparamsobject is written. - JSON body: when the Content-Type is
application/jsonand the body parses,databecomes a JavaScript object and the redundant Content-Type header is dropped, because axios sets it automatically for objects. - Other bodies: form-encoded or plain text data stays a string in
data. - Basic auth:
-u user:passbecomesauth: { username, password }. - Timeout:
--max-time 30is converted to milliseconds,timeout: 30000. - Redirects: axios follows redirects in Node by default, so
maxRedirects: 0is added when the command has no-L. - TLS:
-kadds anhttpsAgentwithrejectUnauthorized: false. Use it only for local testing.
Working with the axios response
curl prints the body and stops; with axios you get a response object to work with. The most useful parts:
console.log(response.status); // 200
console.log(response.headers['content-type']); // header names are lowercase
console.log(response.data); // JSON is already parsed
Two adjustments are common after converting:
- Downloading a file (what
curl -odoes): addresponseType: 'stream'to the config and piperesponse.dataintofs.createWriteStream('out.zip'). Without it, binary data is decoded as text and corrupted. - Keeping 4xx and 5xx responses instead of catching them: add
validateStatus: () => true, then checkresponse.statusyourself, which is closer to how curl behaves.
Limitations
The output targets Node.js. In a browser, httpsAgent, maxRedirects and the form-data package do not apply; use the native FormData and let the browser handle redirects. Proxy flags and client certificates are not converted, and unsupported options are listed as comments above the code. Keep in mind that axios rejects the promise for non-2xx status codes, so wrap the call in try/catch and read error.response for API errors.
Privacy
Everything is converted in your browser, so API keys in the command stay on your device. Prefer the built-in fetch? Use curl to JavaScript. To test the request before writing code, try the API tester, and generate typings for the response with JSON to TypeScript.