# curlconverter: turn a curl command into Python, JavaScript or 27 other targets

> curlconverter is an MIT-licensed TypeScript tool that parses a curl command with a Bash grammar and prints equivalent client code. It is fast for one-off conversions and honest about where the generated code diverges from curl's behaviour.

**curlconverter/curlconverter** — Transpile curl commands into Python, JavaScript and 27 other languages

- Repository: https://github.com/curlconverter/curlconverter
- Website: https://curlconverter.com
- Stars: 8,174 · Forks: 1,017
- Language: TypeScript
- License: MIT
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/curlconverter-curlconverter

## What curlconverter converts, and what it refuses to

The README describes the project in one line: it transpiles curl commands into C, C#, ColdFusion, Clojure, Dart, Elixir, Go, HTTPie, Java, JavaScript, Julia, Kotlin, Lua, MATLAB, Objective-C, OCaml, Perl, PHP, PowerShell, Python, R, Ruby, Rust, Swift, Wget, Ansible, HAR, HTTP or JSON. That list is the product. The audience is anyone who has copied a curl example out of API documentation and now needs the same request expressed in the language of the application they are actually writing.

The project is not an HTTP client. It parses a command and prints code. It never opens a socket, so questions about whether curl is safe to run, or how to run curl in Command Prompt, are outside its scope. It also only handles HTTP. A command such as `curl ftp://example.com` still produces output, but the library variant returns a warning tagged `bad-scheme` reading "Protocol \"ftp\" not supported" alongside the generated code. That pairing of output and warning is the honest part of the design: the tool does not pretend the conversion succeeded.

## Inside the parser: tree-sitter-bash, then a per-language generator

The dependency list in package.json shows the mechanism. `tree-sitter` and `tree-sitter-bash` are runtime dependencies, as is `web-tree-sitter` for the browser build, and `lossless-json` handles JSON bodies without losing precision. A curl command is not a list of flags, it is a line of shell. curlconverter therefore parses it as Bash first, then walks the resulting tree to recover the arguments, which is why the README can claim support for ANSI-C quoted strings, heredocs, stdin redirects, comments, and syntax errors.

After parsing, a generator per target language emits the code. The README states plainly that generators for other languages are less thorough than the Python generator, so the quality of the output is not uniform across the 29 targets. The Python path is the default and the most developed; the Java, Node and PHP families each have several variants (`java-okhttp`, `node-axios`, `php-guzzle` and so on) that differ in which HTTP library the emitted code calls. That is a real design choice: instead of one generic HTTP call per language, curlconverter commits to a specific client library and its idioms.

## Installing curlconverter and converting your first command

The README gives two install paths. For the command line tool, npm installs it globally. The published package name is `curlconverter`, which is what the related search "Curlconverter npm" is looking for.

```bash
npm install --global curlconverter
```

After that, `curlconverter` behaves as a drop-in replacement for curl: you take any curl command, change `curl` to `curlconverter`, and it prints code instead of making the request. The README's own example is a POST with form data.

```bash
curlconverter --data "hello=world" example.com
```

The output is Python using the Requests library, with the body turned into a dictionary.

```python
import requests

data = {
    'hello': 'world',
}

response = requests.post('http://example.com', data=data)
```

To pick a different target, pass `--language <language>`. The accepted values include `python` (the default), `javascript`, `go`, `php`, `ruby`, `rust`, `swift`, `powershell`, `har`, `http` and `json`, plus the library-specific variants such as `node-axios` and `java-okhttp`. To read the command from stdin instead of the argument list, pass `-`.

```bash
echo 'curl example.com' | curlconverter -
```

As a library, curlconverter exports functions that accept either a string of Bash or an array of already-parsed arguments, in the shape of `process.argv`.

```js
import * as curlconverter from 'curlconverter';

curlconverter.toPython('curl example.com');
curlconverter.toPython(['curl', 'example.com']);
```

The README notes that you must add `"type": "module",` to your package.json for that import to work, because curlconverter uses top-level `await` and cannot be loaded with `require()`. If you host it in a browser yourself, it requests two WASM files, `tree-sitter.wasm` and `tree-sitter-bash.wasm`, from the root of your web server, and the README points at the webpack configuration for curlconverter.com as the reference for copying them out of node_modules.

## The redirect trap and other places the generated code is not curl

The most consequential limitation is stated in the README itself. curl does not follow redirects or decompress gzip responses by default, but the generated code inherits whatever the target runtime does by default, because that keeps the output shorter. Python's Requests library follows redirects by default. So unless the original command set the redirect policy explicitly with `-L`, `--location` or `--no-location`, the generated Python will follow redirects while the curl command would not. A conversion can therefore look correct and behave differently in production, and the difference is invisible unless you read the flags.

The Bash handling has similar edges. Shell variables can change how a command parses at runtime, and curlconverter assumes environment variables do not contain characters that would affect parsing. Only simple subcommands such as `curl $(echo example.com)` work; nested commands or subcommands that redirect output will not produce valid code. The README also notes the Bash parser does not support all Bash syntax, and that while curlconverter knows about all 255 curl arguments, most are ignored. Ignored arguments are the quiet failure mode: the output compiles, it just does not do what the original command did.

## curlconverter compared with Postman's import and with writing the client yourself

The obvious alternative for many teams is Postman, which imports a curl command into a saved request you can run and share. The difference in approach is what happens to the output. Postman keeps the request inside its own application and executes it there; curlconverter emits source code that leaves the tool and lives in your repository, next to the rest of your application, with no runtime dependency on curlconverter itself. If your goal is to inspect or replay a request interactively, Postman's model fits better. If your goal is a function in a Python service that calls the same endpoint, curlconverter produces something you can commit.

The other alternative is reading the API documentation and writing the client call by hand. That is often slower but always accurate, and for a single request with unusual flags it may be the better use of an afternoon. curlconverter earns its place when the request is fiddly: multipart bodies, many headers, cookies, a JSON payload that the tool converts into a native object rather than a string. The conversion of JSON data to native objects is listed as a feature, and it is the kind of detail that makes the generated code readable rather than a wall of escaped quotes.

## Maintenance, licence and what an upgrade costs

The repository is not archived. Its last push was on 2026-03-10, and the most recent tagged release listed is v4.12.0 from 2025-02-07, following v4.11.0 in October 2024 and v4.10.1 in May 2024. Releases are spaced months apart, so treat this as a tool that changes slowly rather than one you pin and forget. The package.json version is 4.12.0, matching the latest tag.

Versioning matters here because the output is the interface. A change to a generator changes the code your team copies into a file, and the test directory in the repository suggests the project tracks those outputs deliberately. Upgrading is cheap for the CLI, but if you call the library you are depending on the exact strings returned by functions such as `toPython`, so pin the version and re-run your own conversions after a bump.

The licence is MIT, with copyright attributed to Nick Carneiro. MIT is permissive: it allows commercial use and modification, and it requires the licence and copyright notice to be preserved. That is a description of the terms, not legal advice; if you redistribute curlconverter inside a product, have your own counsel read the LICENSE file, which is present at the repository root.

## Conclusion

Adopt curlconverter when you are pasting a curl command from API documentation into a real client and want the boilerplate written for you, especially for Python or JavaScript. Do not adopt it as a general HTTP client, a Postman replacement, or a way to run curl on Windows, because it never sends a request and only HTTP is supported. Before trusting it in a codebase, convert one command with a redirect flag such as -L and compare the generated code against curl's own defaults, then check the warnings array from toPythonWarn for your target language.

## FAQ

### How can I convert a curl command to a PowerShell command with curlconverter?

Pass the PowerShell target explicitly with --language powershell, or use powershell-webrequest for the Invoke-WebRequest variant. The README lists both among the accepted --language values, and notes that generators other than Python are less thorough.

### How do I install curlconverter?

Install the command line tool with npm install --global curlconverter, or install the library into a project with npm install curlconverter. The library must be imported as an ES module, so your package.json needs "type": "module", because it uses top-level await.

### Does curlconverter send the request, or only print code?

It only prints code. The README describes it as a drop-in replacement for curl where you change curl to curlconverter and it prints code instead of making the request, and only HTTP is supported.

### Why does the generated Python follow redirects when my curl command did not?

Because the generated code uses the target runtime's defaults to stay short. Python's Requests library follows redirects by default, so unless the original command set -L, --location or --no-location, the generated code will not handle redirects the same way as the curl command.

## Sources

- [curlconverter/curlconverter on GitHub](https://github.com/curlconverter/curlconverter)
- [License: MIT](https://github.com/curlconverter/curlconverter/blob/master/LICENSE)
- [Project website](https://curlconverter.com)
- [README](https://github.com/curlconverter/curlconverter/blob/master/README.md)
- [Releases](https://github.com/curlconverter/curlconverter/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/curlconverter-curlconverter
