curl to Code Converter
Turn a curl command into JavaScript fetch, axios, Node.js or Python requests code, preserving headers, body and authentication.
A flag's value is not a flag, and it used to become the URL
The parser knew the flags it converts and skipped anything else beginning with a
dash. That is exactly right for -k, -L, -s,
-v — they take no value. It is wrong for every flag that does.
| Command | Requested | Now |
|---|---|---|
--max-time 30 https://api.example.com/users | 30 | https://api.example.com/users |
--connect-timeout 5 https://api.example.com | 5 | https://api.example.com |
--retry 3 https://api.example.com | 3 | https://api.example.com |
-m 30 https://api.example.com | 30 | https://api.example.com |
--output report.json https://api.example.com | report.json | https://api.example.com |
-o out.txt https://api.example.com | out.txt | https://api.example.com |
--resolve example.com:443:1.2.3.4 https://example.com | example.com:443:1.2.3.4 | https://example.com |
The generated code was syntactically fine and requested the wrong thing, which is the worst kind of wrong for a code generator — you get output, so you assume it worked. Two changes fix it: the parser now knows the 56 flags that consume the next token, and when several bare tokens remain it prefers the one shaped like a URL rather than whichever came first. Either alone would handle most cases; together they also handle a flag nobody has heard of.
All 4 commands using flags that genuinely take no value parse exactly as they did before.
And a header with no colon used to eat its own last letter
The name was everything before the colon and the value everything after it. With no colon the search returns −1, and slicing to −1 means "all but the last character".
| Written | Produced | Now |
|---|---|---|
-H "Accept" | Accep: Accept | (none) |
-H "X-Trace" | X-Trac: X-Trace | (none) |
-H "Accept: application/json" | Accept: application/json | Accept: application/json |
-H "X-Empty:" | X-Empty: | X-Empty: |
A single off-by-one with no error, in the one place you are least likely to re-read the output. A header without a colon is not a header, so it is skipped now. Real ones are untouched, including one with an empty value.
Two smaller things the generated code could not previously promise
The Python output calls requests.<method>, and that function
exists for the 7 methods the library gives shortcuts for.
Ask curl for -X PURGE — a real method, used by several caches — and
the generated line called something that does not exist.
| Method | Shortcut? | Generated call |
|---|---|---|
| GET | yes | requests.get(url) |
| POST | yes | requests.post(url) |
| PATCH | yes | requests.patch(url) |
| PURGE | no | requests.request("PURGE", url) |
| LOCK | no | requests.request("LOCK", url) |
| REPORT | no | requests.request("REPORT", url) |
3 of those 6 now get the general form, which works for all of them.
The other was -u, which turns a username and password into a Basic
authorization header by base64-encoding them. The browser's base64 function
works on Latin-1 code units, and curl sends UTF-8 bytes. Those are the same
thing for ASCII and not otherwise.
| Credentials | Produced | What curl sends |
|---|---|---|
ada:hunter2 | Basic YWRhOmh1bnRlcjI= | Basic YWRhOmh1bnRlcjI= |
user: | Basic dXNlcjo= | Basic dXNlcjo= |
rené:päss | Basic cmVu6Tpw5HNz | Basic cmVuw6k6cMOkc3M= |
user:пароль | threw an error | Basic dXNlcjrQv9Cw0YDQvtC70Yw= |
A Cyrillic password threw outright. The accented one is the quieter failure: it was accepted, encoded as the wrong bytes, and produced a header that would not have authenticated. ASCII credentials — nearly all of them — are byte-identical to before.
How to use
- Copy a curl command, or take one from your browser's network tab.
- Paste it in, including all of its flags.
- Choose your target language or library.
- Read the generated code and remove anything you do not need.
- Strip credentials before sharing the result with anyone.
Frequently asked questions
Where do I get a curl command from?
Your browser's developer tools. In the network tab, right-clicking any request offers 'copy as curl', which captures the complete request including headers and cookies. It is much the fastest way to reproduce in code something you have just watched the browser do.
Will the generated code work as it stands?
Usually, with two caveats worth knowing. Requests copied from a browser routinely carry session cookies and authentication headers that expire within hours, plus browser-specific headers a server may not expect from a script. Strip what you do not need rather than sending all of it blindly.
Should I be careful about sharing these?
Very. A copied curl command routinely contains session cookies, bearer tokens and API keys sitting in plain sight. Pasting one into a bug report, an issue tracker or a chat hands over whatever access it carries, and this happens often enough to be a well-recognised leak vector.
What is the difference between fetch and axios?
Fetch is built into browsers and modern Node with no dependency to install; axios is a library that adds automatic JSON handling, request interceptors, timeouts and clearer error semantics. Fetch notably does not reject on HTTP error statuses — a 404 resolves successfully and you have to check the status yourself, which catches people out constantly.
Does this handle file uploads?
Multipart form uploads convert, though the file itself obviously cannot travel with the command — the generated code references a path or a file object that you supply. The boundary handling is normally left to the library rather than set by hand, which is why the generated code is shorter than the curl original.
Does my command get sent anywhere?
No. The parsing and conversion run entirely in your browser and nothing is transmitted. That matters a great deal here, given how routinely these commands contain live credentials for real systems.
Why does the generated Python differ from the curl?
Because libraries set sensible defaults that curl requires you to state explicitly. Content-type headers for JSON bodies, encoding, and connection reuse are usually handled for you, so a faithful conversion produces shorter code rather than a line-by-line translation.
🔒 This tool runs entirely in your browser. Nothing you enter is uploaded, logged, or stored.