cURL to Go

Convert a cURL command into a Go net/http request.

cURL Command
Go (net/http) Output
Go (net/http) code appears here

Related Tools

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
  • -u Basic Auth mapped to req.SetBasicAuth
  • -F/--form uploads built via multipart.Writer, with a TODO stub for file fields
  • -k/--insecure mapped to a custom Transport with InsecureSkipVerify: 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.