Skip to main content

cURL to Code

cURL to Code turns a curl command into fetch, axios, Python requests, Go, PHP or Ruby in your browser. It parses the command as shell — single quotes, double quotes, ANSI-C escapes, line continuations and clustered flags — so a payload with a space or an apostrophe in it survives intact.

Local-only
Language
cURL command
0 B1 lineLn 1, Col 1
JavaScript fetch · Any modern browser or Node 18+read-only
0 B1 line

How does cURL to Code work?

The conversion looks trivial and is not, because a curl command is shell rather than a data format. Three things break a naive implementation, and all three are common in commands copied out of a browser's developer tools.

The quoting is the hard part

-d '{"name":"Ada Lovelace"}' is one argument containing a space. -H "Authorization: Bearer $TOKEN" contains a variable the shell has already expanded or has not. --data $'line\nbreak' uses ANSI-C quoting, where \n is a real newline — and the same characters inside ordinary single quotes are a literal backslash and an n. No regular expression can undo that, because the escaping rules differ inside each quoting style. So the command is tokenized by a small state machine that tracks which quote it is inside, and the emitters only ever see finished arguments.

Clustered flags are three different things

-sSL is three bare flags. -XPOST is one flag with its value attached. -H'X-Trace: 1' is a value-taking flag whose value contains punctuation and a space. They are told apart by walking the letters and stopping at the first one that takes a value, which is what curl's own parser does — and it is why -sSXPOST comes out as a POST rather than as six flags.

What the generated code refuses to invent

-d @payload.json reads a file at run time. The file is not in the command, so the body cannot be inlined: the generated code names the file and leaves the read for you, because guessing would produce code that silently posts the wrong payload. -k is the other deliberate omission — the generated code keeps certificate verification on and says so in a comment, since an insecure flag copied into a codebase is exactly how it ends up in production.

Everything else translates directly: -u becomes the Authorization: Basic header it actually sends, -b becomes a Cookie header, -F becomes a multipart form with the boundary left to the HTTP client, and -G moves the data into the query string where curl puts it.

curl

curl -X POST 'https://api.example.com/v1/orders' \
  -H 'Content-Type: application/json' \
  -d '{"total":148.5}'

fetch

const response = await fetch("https://api.example.com/v1/orders", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "total": 148.5
  }, null, 2),
});

const data = await response.json();

What does a curl command look like as fetch?

The command a browser's "Copy as cURL" produces, translated. The headers, the method and the body all survive the shell quoting, which is the part a naive converter gets wrong.

curl

curl -X POST 'https://api.example.com/v1/orders' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer YOUR_API_TOKEN_HERE' \
  -d '{"total":148.5}'

fetch

const response = await fetch("https://api.example.com/v1/orders", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: "Bearer YOUR_API_TOKEN_HERE",
  },
  body: JSON.stringify({
    "total": 148.5
  }, null, 2),
});

const data = await response.json();

A JSON body is emitted as JSON.stringify({...}) — and as the object itself for axios and Python requests — so the generated code reads as data rather than as an escaped string. The Authorization header is reproduced because it was in the command — treat the generated file as you would treat the command.

What options and edge cases does cURL to Code support?

Supported options and what each becomes
ParameterTypeDefaultBehaviour & edge cases
-X, --requestmethodPOST if there is a bodySets the HTTP method. Without it the method is POST when the command has a body, form field or -I, and GET otherwise — which is exactly curl's own rule.
-H, --headerheadersnoneRepeated once per header. The -H "Name;" form removes a header rather than setting one; generated code simply does not send it, and the page says so rather than inventing a value.
-d, --data*bodynoneMultiple -d flags are joined with &, which is what curl does. -d @file cannot be inlined — the file is not in the command — so the generated code names it and leaves the read to you.
--data-urlencodebodyform-encodedThe value is percent-encoded before it becomes the body, so a space or an ampersand in the value is safe. That is the whole point of the flag.
-F, --formmultipartnoneBecomes a multipart form. -F name=@file attaches a file part and -F name=value sends a text part; the boundary is left to the HTTP client, because setting it by hand is how a multipart request ends up malformed.
-u, --userbasic authnoneBecomes the Authorization: Basic header curl actually sends, with the credential base64-encoded. It is visible in the generated code because it was visible in the command.
-b, --cookiecookie headernoneA semicolon-separated cookie string becomes one Cookie header, parsed into name/value pairs so the generated code reads as data rather than as a magic string.
-G, --getquery stringoffMoves every -d and --data-urlencode field into the URL's query string and clears the body, which is how curl issues a GET with a long parameter list.
-k, --insecurenoteoffNot reproduced. The generated code verifies certificates and carries a comment saying the original did not. Copying an insecure flag into a codebase is how it survives to production.
--jsonbody + headersnoneSets the body, Content-Type: application/json and Accept: application/json, matching the shorthand curl added in 7.82.
-o, -m, --retry, --proxyignored—Local output paths, timeouts, retry counts and proxy settings have no equivalent in the generated request, so they are consumed and dropped rather than mistranslated.
Output sizebytes256 KBA command is short by nature; the ceiling exists so a pasted file is declined rather than tokenized.

Frequently asked questions

Does it handle commands copied from Chrome or Firefox devtools?

Yes — that is the main source of the commands people bring here. Devtools emits single-quoted arguments, a backslash-newline continuation between them, and often a `--compressed` flag and a long cookie header. All three are handled: the continuation is a line break rather than content, --compressed is noted and dropped because every client here negotiates compression itself, and -b becomes a Cookie header.

What happens to -d @payload.json?

The generated code names the file and leaves the read for you to complete. It cannot be inlined: the file's contents are not in the command, and inventing a placeholder body would produce code that silently posts the wrong payload — a bug that only shows up against a real API. The tool tells you which file it saw rather than guessing.

Why is -k not carried over?

Because copying it is how an insecure flag reaches production. The generated code keeps certificate verification on and carries a comment saying the original disabled it, so the decision stays visible and deliberate. If you genuinely need it, the comment says where to change it — and in Node it is one environment variable rather than a code change.

How are shell variables and escaped characters handled?

Variables are left as written, because the shell has already expanded them by the time you paste the command — a literal $TOKEN in the text means the variable was not expanded, so it stays as a placeholder you can see. Escaping is interpreted properly: inside double quotes a backslash only escapes the five characters POSIX says it does, inside single quotes nothing is escaped at all, and $'…' is ANSI-C quoting where \n is a real newline.

Which target should I pick?

fetch if the code is going into a browser or Node 18+, which is most cases now. axios when the project already uses it, since it handles JSON serialisation and error statuses for you. Python requests for a script, Go for a service, PHP or Ruby when that is the codebase. All six produce the same request; they differ only in how much ceremony the language needs.

Is my command sent anywhere?

No. Parsing and generation both run in this tab. That matters because a curl command frequently contains a live API key, a session cookie or a bearer token — the Authorization header in the sample above is exactly that. Nothing is transmitted, and there is no API route for it to be transmitted to.