The cURL you copied from DevTools has more in it than the code shows
You right-click a network request in Chrome, "Copy as cURL", and paste it into the cURL to Code Converter. Out comes a JavaScript fetch call. It looks right. It runs. And four things in the original command — the -k that skipped a self-signed cert, the --compressed that set Accept-Encoding, the -F that uploaded a file, the absence of -L that stopped curl following a 302 — quietly stopped existing. The code does something different from what the cURL did. The converter is a regex parser, not a shell tokenizer, and it drops what its regexes don't catch.
Fourteen languages, not three
The FAQ says "JavaScript, Python, PHP." The actual count is 14, grouped in the picker by family:
- JavaScript (4): fetch, axios, node-fetch, TypeScript fetch
- Python (2): requests, httpx
- PHP, Go, Ruby, Java, C#, Rust, Kotlin, Swift (one each)
Pick the one your codebase uses, not the default. The default is javascript-fetch, and it has a problem the others don't.
The parser is regex, not a shell tokenizer
cURL is a shell command with quoting rules. The converter doesn't run a shell — it runs regular expressions over the flattened string. Two consequences bite:
-
Unquoted headers are silently dropped. The header regex is
-H ['"]([^'"]+)['"]— it requires quotes.-H Content-Type:application/json(no quotes) matches nothing and vanishes. Chrome's "Copy as cURL" always quotes, so this only bites hand-typed commands — but it bites silently, no warning. -
A quote inside a value ends the value.
[^'"]+stops at the first quote of either kind.-H "X-Custom: it's a test"capturesX-Custom: itand drops the rest. Use the other quote char or escape — the parser doesn't.
Line continuations (\ + newline) collapse to spaces, and all whitespace runs become a single space. Fine for flags, destructive for pretty-printed JSON — the indentation is gone before generation runs.
The four flags that silently disappear
Verified by reading every generator in the file:
-
-k/--insecureis parsed but never emitted.result.insecureis set; no generator reads it. A cURL that skipped TLS verification converts to code that verifies TLS. If you hit a self-signed endpoint, the generated code throws where the cURL succeeded — and nothing in the output tells you why. -
--compressedis parsed but never emitted. Same shape:result.compressedis set, never used. cURL with--compressedsendsAccept-Encoding: gzipand decodes the response. The generated code does neither. A response that was only legible because cURL decompressed it now comes back as raw bytes. -
-F/--formis parsed but never emitted.formDatais collected — the UI even shows a "Form data" badge — but no generator builds a multipart body. Acurl -F file=@photo.pngconverts as if it had no body at all. Silent data loss; the badge is the only trace. -
Redirect semantics flip. cURL without
-Ldoes not follow redirects. The generator emitsredirect: 'manual'(fetch) /allow_redirects=False(requests) only whenfollowRedirects === false— but with no-L,followRedirectsisundefined, notfalse, so the clause is skipped.fetchdefaults to following redirects;requestsdefaults to following. So "no-L" in cURL becomes "follow redirects" in the output — the opposite behavior, with no visible difference in the generated code.
The body that guesses JSON from one character
Every generator decides json= vs data= (or JSON.stringify vs a raw string) by data.startsWith('{'). One character. If the body starts with {, it's treated as JSON; otherwise as a string. A form-encoded body that happens to start with { gets JSON.stringify'd in fetch and json= in Python — wrong content type, but valid syntax. A non-JSON string like {not json} becomes JSON.stringify({not json}), a syntax error. The heuristic reads shape, not content; it never parses the JSON to check. If your body is real JSON, fine. Otherwise edit the output.
Gotchas
- JS fetch output isn't runnable as-is. It's
const response = await fetch(...)at top level — noasyncwrapper. Paste it into a browser console and you get a syntax error. Wrap it inasync function main() { ... } main();, or run it where top-level await is legal. The Python and PHP outputs run as printed. - Ruby and C# break on non-standard verbs. Ruby generates
Net::HTTP::Post,Net::HTTP::Get— class lookups.PROPFINDbecomesNet::HTTP::Propfind, which doesn't exist. C# does the same withHttpMethod.Propfind. Standard verbs work; anything else throws at runtime. - C# hardcodes
application/json. The body becomesStringContent(data, Encoding.UTF8, "application/json")regardless of yourContent-Typeheader or the body's shape. Form data, text, XML — all labelled JSON. Set the content type yourself. - Bearer tokens stay in headers. The parser detects Bearer and stores
auth.bearer, but generators emit the originalAuthorizationheader, not a dedicated auth API. Fine — just don't expect.bearerAuth().
Summary
- The converter outputs 14 languages (4 JS variants, 2 Python, plus PHP/Go/Ruby/Java/C#/Rust/Kotlin/Swift), not the three the FAQ names — pick the one your stack uses.
- It's a regex parser, not a shell tokenizer: unquoted
-Hheaders vanish, quotes inside values truncate them, and whitespace in JSON bodies is collapsed before generation. - Four flags silently disappear:
-k(TLS verify comes back on),--compressed(no Accept-Encoding),-F(form data parsed, never emitted — data loss), and the absence of-L(no-follow flips to follow, because the guard checks=== falsenot falsy). - The JSON-vs-string choice is
data.startsWith('{')— one character, shape not content. Edit the output for non-JSON bodies. - JS fetch output is
awaitat top level — wrap it in an async function before running. Ruby/C# break on non-standard verbs; C# hardcodesapplication/jsoncontent type. - Convert in the cURL to Code Converter. To test the request live: API Tester. To inspect headers: HTTP Headers Parser. For turning a response into types: JSON to TypeScript. For a different conversion direction: SQL to MongoDB.