Curl Command Converter

Paste a curl command and get the same request as JavaScript fetch, Python requests, Node axios, PHP cURL or PowerShell. Parsed in your own browser tab.

🌐 Español

🔒 Private by design: your text is processed locally in your browser and never uploaded to any server.

Pasting a command and picking a language

  1. Copy a curl command from API documentation, from a shell script, or from your browser’s network panel via right-click and Copy as cURL. Multi-line commands with a trailing backslash on each line need no cleanup.
  2. Paste it into the box above.
  3. Set Target language to one of JavaScript (fetch), Python (requests), Node.js (axios), PHP (cURL) or PowerShell (Invoke-RestMethod). JavaScript (fetch) is preselected.
  4. Click Curl Command Converter. The code replaces the paste box, and Copy to clipboard puts it on your clipboard.

Only one language is rendered at a time. That is a deliberate choice: what you usually want is a block you can drop straight into a file, not five stacked variants to scroll past.

The flags it reads, and the ones it quietly drops

Parsing runs in two stages. First a shell-style tokenizer splits the text the way bash would, which is what makes quoting behave. Inside single quotes nothing at all is special, exactly as in a real shell. Inside double quotes only the handful of escapes bash itself recognises are processed. Outside quotes, a backslash immediately before a newline is treated as a line continuation and both characters vanish.

Then the tokens are read as curl flags:

Flags that change how curl behaves without changing the request are recognised and skipped, among them --compressed, -k, -L, -s, -v, -i, -f, -g, -4 and -6. Anything else beginning with a dash is skipped too.

Method selection follows curl, not a default

If the command has no -X, the method is not simply assumed to be GET. A command carrying any data flag becomes a POST, and only a command with no body at all becomes a GET. That mirrors curl’s own behaviour, and it is the single most common surprise for people who expect a converter to hardcode GET.

The Python output goes one step further and uses the bound helper for the method where one exists, so a POST becomes requests.post(url, ...). An unusual method such as PURGE has no helper, so it falls back to requests.request('PURGE', url, ...) instead.

JSON bodies, and the one line to add for fetch

When the body starts with a brace or a bracket and parses as JSON, four of the five outputs print it as a real structure rather than a string, and only PowerShell keeps it as text. Python gets a dict literal with True, False and None spelled the Python way. PHP gets an array literal with arrows, passed through json_encode(). The fetch and axios outputs get the parsed object printed as a JavaScript literal.

That is correct for axios, whose data field serialises an object for you. It is not correct for fetch as written: the Fetch API expects body to be a string, and a plain object would be stringified into something useless. Wrap it yourself:

body: JSON.stringify({
  "sku": "A-19",
  "qty": 2
}),

PowerShell keeps the body as a plain string in every case, which works because Invoke-RestMethod sends it verbatim. If you would rather send a structure there, replace the string with a hashtable and pipe it through ConvertTo-Json. When the body is not JSON at all, for instance form-encoded pairs, every language receives it as a string. Formatting a messy body before you convert it is easier in the JSON Formatter, which will also tell you if it is not valid JSON in the first place.

Quote escaping is different in PowerShell, on purpose

Every generator wraps its strings in single quotes, and the rule for escaping them is not shared. JavaScript, Python and PHP all use a backslash to protect a literal quote or a literal backslash. PowerShell has no escape character inside single quotes at all, so a backslash is always just a backslash and the only way to write a quote is to double it. A body containing it's fine therefore comes out as 'it\'s fine' in Python and 'it''s fine' in PowerShell.

Newlines diverge as well. JavaScript and Python cannot hold a raw newline inside a single-quoted string, so real line breaks are converted into escape sequences. PHP and PowerShell both accept a literal newline, and in PHP the characters backslash and n mean nothing special inside single quotes, so converting them would change the value. They are left alone there.

Known gaps: multipart, encoding and flag order

Multipart form uploads through -F are not converted. Worse, -F is not on the list of flags known to take a value, so its argument is left loose in the command and may be mistaken for the URL if it appears before the real one. The same applies to other value-taking flags that do not affect the request, such as -o. If the output shows a strange URL, delete those flags from the command and convert again.

Percent-encoding is not applied to --data-urlencode values. Cookies handed over with -b are turned into a single header rather than a cookie jar. Nothing is executed here either: you get code to read and run yourself, never a live request.

Two neighbours pair well with this page. A bearer token pulled out of a converted header can be inspected with the JWT Decoder, and a query parameter that really does need escaping can go through URL Encode first. Both live on the developer tools hub along with the rest of the request-debugging set.

See it in action

Screenshot of the Curl Command Converter tool with the sample input “curl -X POST https://api.example.com/v1/convert …”, Target language set to JavaScript (fetch)
Curl Command Converter mid-process: the sample input “curl -X POST https://api.example.com/v1/convert …”, Target language set to JavaScript (fetch).
Screenshot of the Curl Command Converter result screen showing the generated output “fetch('https://api.example.com/v1/convert', { me…”
The finished result: the generated output “fetch('https://api.example.com/v1/convert', { me…”. The download link is a local blob URL — the file never leaves your device.

Frequently asked questions

Can I see the same command in a second language without pasting it again?

Not in one go. Once the code appears, the paste box and the Target language dropdown are replaced by the result, and the button that brings them back also empties the box. Keep the command on your clipboard if you plan to compare two languages, then paste, convert, copy the output, start over and pick the other one.

The output box says it could not convert my command. What is it actually checking?

Four things, and each has its own explanation in that message. The text has to start with the word curl. A flag that takes a value has to have one after it. A header has to contain a colon so it can be split into a name and a value. And there has to be at least one bare word that can serve as the URL. The explanation is written into the output box itself rather than shown as a banner, so read the box.

Does a command copied from the Chrome DevTools network panel work as-is?

Yes, and that is the shape it was built around. Those commands arrive as several physical lines with a backslash at the end of each one, and the tokenizer joins them the way a shell would before it looks at a single flag. Single-quoted arguments are taken completely literally, so a header value full of colons, ampersands or slashes survives intact.

What happens when the same command carries two data flags?

Their values are joined in order with an ampersand between them, which is what curl itself does with repeated data options. All the usual spellings feed the same list, including the raw, binary, ascii and urlencode variants. One thing to watch is that the urlencode variant is treated as a plain value here, so its contents are copied across without being percent-encoded for you.

Where does HTTP Basic auth end up in each language?

The user and password are split at the first colon, so a password containing further colons stays whole. Python receives them as the auth tuple that requests expects, axios receives its own auth object with username and password fields, PHP sets CURLOPT_USERPWD, and PowerShell base64-encodes the pair and adds the header itself. The fetch output wraps the pair in a call to btoa, which is a browser function, so a Node script needs a Buffer instead.

Is it safe to paste a command that still has a live token in it?

The parsing and the code generation are ordinary JavaScript running inside this page, so the command you paste stays in the tab and is not transmitted anywhere. That is the reason this exists as a page rather than an API. Copied requests are full of real bearer tokens, session cookies and keys, and pasting one into a converter that does the work on somebody else's machine hands them a working credential.

Related tools