cURL to Go
Convert a cURL command into a Go net/http request.
Related Tools
Convert a cURL command into a Python requests call.
Convert a cURL command into a Rust reqwest request.
Generate Go structs with JSON tags from a JSON document.
Beautify and pretty-print JSON with configurable indentation.
Convert a cURL command into a Node.js fetch call.
Convert a cURL command into a PHP curl_setopt call.
Documentation
What is curl-to-Go?
This tool parses a curl command line — method, URL, headers, body, form fields, Basic Auth, and the -k/--insecure flag — and emits an equivalent Go program built on the standard library's net/http package. No third-party HTTP client is pulled in, so the output compiles with nothing more than a stock Go toolchain.
How it works
The curl string is tokenized respecting quoted arguments, then walked flag by flag into a structured request description (method, url, headers, data, form, auth, cookie, insecure). The Go emitter builds an http.NewRequest call from that structure: a -d/--data body becomes a raw backtick string wrapped in strings.NewReader(...) — the exact bytes curl would have sent, never re-parsed or re-encoded as a Go struct. Headers become req.Header.Set(...) calls, and -u user:pass becomes req.SetBasicAuth(user, pass) — Go's own idiom for Basic Auth, rather than a manually-built Authorization header. Imports are computed on the fly: strings only appears if there's a body, bytes/mime/multipart only for -F uploads, and crypto/tls only when -k is present.
Features
- Zero-dependency output — only Go standard library packages
- Body passed through byte-for-byte via
strings.NewReader, never reconstructed -uBasic Auth mapped toreq.SetBasicAuth-F/--form uploads built viamultipart.Writer, with a TODO stub for file fields-k/--insecure mapped to a customTransportwithInsecureSkipVerify: true- Minimal, readable output — one
func main(), no framework boilerplate
Example
Input: curl -X POST https://api.example.com/v1/login -H "Content-Type: application/json" -u admin:s3cret -d '{"username":"admin","remember":true}'
Output:
package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
req, err := http.NewRequest("POST", "https://api.example.com/v1/login", strings.NewReader(`{"username":"admin","remember":true}`))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.SetBasicAuth("admin", "s3cret")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
respBody, _ := io.ReadAll(resp.Body)
fmt.Println(resp.StatusCode, string(respBody))
}Common errors
The generated code always checks err after http.NewRequest and client.Do, but panics rather than returning the error up the call stack — fine for a quick script, not for production code, where you'd want to return error from a function instead. File uploads via -F key=@path leave a // TODO comment because the generator runs in your browser and has no access to the actual file on disk — you fill in the io.Copy yourself.
Best practices
Run gofmt on the output before committing it — the generator emits correct but unformatted Go (tabs for struct-like blocks, no alignment). Replace the panic(err) calls with proper error returns for anything beyond a throwaway script, and never ship InsecureSkipVerify: true to production — it disables TLS certificate validation entirely.
Frequently Asked Questions
Why net/http instead of a third-party client?▾
net/http is in Go's standard library — no extra dependency needed, and it's what most idiomatic Go HTTP code is built on anyway.
How is the request body handled?▾
Passed through as the raw string via strings.NewReader, exactly as curl would send it — not re-encoded as a Go struct, so the payload's bytes are guaranteed to match what -d sent.
Does it support -F / --form uploads?▾
Yes — it builds a multipart.Writer, writing text fields directly and stubbing a TODO comment for file fields (Go's multipart file attachment needs an actual file handle, which the generator can't supply since it doesn't have access to your filesystem).
What does -k / --insecure become?▾
An http.Client configured with a custom Transport whose TLSClientConfig.InsecureSkipVerify is set to true — the direct Go equivalent of curl -k. Only use this against endpoints you trust.