Converting cURL to fetch and axios
Turn cURL commands from API docs into working JavaScript. Learn how methods, headers, and bodies map to fetch and axios — and what needs manual review before you ship.
Updated July 2026 · 6 min read
Almost every API documentation page gives you a curl example. It is a great way to try a request from the terminal, but at some point you need that request running inside an actual app. This guide shows how a cURL command maps onto JavaScript's fetch and the axios library, which parts translate cleanly, and which ones need a human eye.
A cURL command, piece by piece
Here is a typical POST request from an API doc:
curl -X POST https://api.example.com/login \
-H "Content-Type: application/json" \
-d '{"username":"dev","password":"secret"}'Three things carry over to JavaScript:
- Method —
-X POSTbecomesmethod: "POST". - Headers — each
-Hbecomes an entry in theheadersobject. - Body — the
-dpayload becomes the requestbody.
The fetch version
const res = await fetch("https://api.example.com/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username: "dev", password: "secret" }),
});
if (!res.ok) {
throw new Error(`Request failed: ${res.status}`);
}
const data = await res.json();Two details trip people up. First, the body must be a string — hence JSON.stringify. Second, fetch does not throw on a 404 or 500; it only rejects on network errors. That is why the if (!res.ok) check is essential, not optional.
The axios version
import axios from "axios";
const { data } = await axios.post(
"https://api.example.com/login",
{ username: "dev", password: "secret" },
{ headers: { "Content-Type": "application/json" } }
);axios does more for you: it serializes the body to JSON, sets the content type, parses the response, and throws automatically on 4xx and 5xx responses. That is less boilerplate, at the cost of an extra dependency.
fetch vs. axios at a glance
| fetch | axios | |
|---|---|---|
| Built in? | Yes (browsers, Node 18+) | No — a dependency |
| JSON parsing | Manual (await res.json()) | Automatic |
| Throws on 4xx/5xx | No — check res.ok | Yes, by default |
| Interceptors / cancellation | Manual | Built in |
For a couple of requests, fetch keeps your bundle lean. For a larger app with shared auth headers, retries, or request cancellation, axios's built-in features earn their place.
What needs manual review
Automated conversion handles the common case, but watch for these:
- Shell quoting. Single vs. double quotes and escaped characters in the terminal do not always map cleanly to JavaScript strings — double-check the body.
- Multipart uploads.
-Ffile uploads need aFormDataobject, not a JSON body. - Authentication. A
-H "Authorization: Bearer ..."header from a doc often contains a live token. Move it to an environment variable before committing. - Cookies and redirects. Flags like
--cookieand-Lhave separate options in fetch/axios (credentials, redirect handling).
A safe workflow
- Paste the cURL command into a converter to get a starting point.
- Read the generated code — confirm the method, headers, and body match your intent.
- Replace any hard-coded secrets with environment variables.
- Add error handling (
res.okfor fetch; try/catch for axios). - Test against a development endpoint before pointing it at production.
Try it
The DevBox cURL Converter generates both fetch and axios versions side by side so you can pick the one that fits your project. Format the response with the JSON Formatter to confirm the shape of the data you get back.
Frequently asked questions
What is the difference between fetch and axios?+
fetch is built into browsers and Node 18+, returns a Response you must call .json() on, and does not throw on HTTP error statuses. axios is a library that parses JSON automatically, throws on 4xx/5xx by default, and supports interceptors and request cancellation out of the box.
Why does fetch not throw on a 404?+
fetch only rejects on network failures, not HTTP error codes. A 404 or 500 still resolves successfully, so you must check response.ok (or response.status) yourself before reading the body.
How do I send a JSON body with fetch?+
Set the Content-Type header to application/json and pass JSON.stringify(data) as the body. Forgetting either one is the most common reason a POST request fails.
Can I convert any cURL command to fetch automatically?+
Simple commands with a method, headers, and a JSON body convert cleanly. Multipart uploads, cookies, client certificates, and shell-specific quoting often need manual review, so always read the generated code before shipping it.
Should I commit the auth header from a cURL example?+
No. cURL examples from docs often include a real token or API key. Move secrets into environment variables and never commit them to source control.