Skip to content
100% Client-SideZero Uploadfetch() Output

cURL to Fetch Converter — Client-Side & Secure

Paste a cURL command and get production-ready fetch() code: async/await by default, headers as a plain object, JSON bodies wrapped in JSON.stringify with a pretty-printed literal, and basic auth pre-encoded as an Authorization header. Conversion happens entirely in your browser.

  • Zero upload, ever

    Parsing and code generation run in your browser — URLs, headers, and tokens never touch a server.

  • Live 100 ms conversion

    Output updates as you type or paste, with one-keystroke copy via Cmd/Ctrl + Enter.

  • Idiomatic output

    async/await, JSON.stringify, and response.json() — the way you would write it by hand.

Paste a cURL command to convert

Examples
100% Client-Side: Tokens & credentials never leave your browser.

cURL command

Paste a cURL command — idiomatic code appears here instantly, converted entirely in your browser.

Technical documentation

How cURL maps to fetch()

Every -H flag becomes an entry in the headers object, -X or --request sets the method property, and data flags become the body. When the Content-Type is application/json (or the body parses as JSON), the payload is embedded as a formatted object literal inside JSON.stringify — readable, diffable, and safe to edit. Form data keeps a plain string body with the urlencoded content type curl would send.

Basic auth from -u is converted to an Authorization: Basic header using base64 computed at conversion time, so the generated snippet has zero runtime dependencies — no btoa call, no Buffer polyfill. Credentials embedded in the URL are extracted into the same header automatically.

Quoting edge cases the converter handles

cURL commands copied from Chrome DevTools often arrive with $'…' ANSI-C quoting, escaped double quotes inside JSON bodies, and trailing backslashes joining multi-line commands. The tokenizer processes all of these the way bash would, then unescapes your body once — so '{"name": "John \"Doe\""}' arrives in the generated code exactly as curl would transmit it.

The parser also drops the Content-Length header (fetch computes it), merges repeated headers case-insensitively with the last value winning, and removes headers set with an empty value using curl's -H 'Header:' unset syntax.

Using the output in Node.js and TypeScript

The generated code runs in every modern browser and in Node.js 18+, where fetch is built in via undici. Top-level await needs an ES module context (type: module, or a .js file in a modern setup); otherwise wrap the snippet in an async function as shown.

In TypeScript the snippet type-checks as-is; the parsed JSON literal infers its type structurally. For stricter APIs, type response data with a generic helper such as response.json() as Promise<MyType> — the shape is already visible in the snippet.

fetch() versus curl behavior to know about

fetch follows redirects by default (like curl -L) and does not verify the same TLS options, so flags such as -k/--insecure have no equivalent and are ignored during conversion. Similarly, curl's --compressed becomes fetch's automatic decompression — nothing to configure.

One deliberate difference: a GET request carrying -d data is converted to query parameters, because the Fetch spec forbids GET bodies and browsers throw a TypeError. The wire request stays equivalent to what curl sent.

Frequently asked questions

Is my API token safe when converting cURL to fetch?

Yes. The conversion runs entirely in your browser — the command is never sent to a server, stored, or logged. The padlock badge in the workspace confirms the zero-network guarantee.

Does the converter support POST, PUT, PATCH, and DELETE?

Yes. The verb is taken from -X/--request, or inferred automatically: POST when a body flag like -d or --data-raw is present, HEAD for -I, and GET otherwise. Custom verbs pass through verbatim.

Why does the output use JSON.stringify instead of a raw string?

Wrapping a pretty-printed object literal in JSON.stringify keeps the snippet readable and editable while producing byte-identical request bodies. If the body is not valid JSON, the converter falls back to a plain string body.

How is basic auth (-u) converted?

The user:password pair is base64-encoded during conversion and emitted as an Authorization: Basic header, matching exactly what curl sends on the wire — with no runtime encoding code in the snippet.

Can I run the generated fetch() code in Node.js?

Yes — Node.js 18 and later include fetch natively. Use an ES module for top-level await, or wrap the snippet in an async function for CommonJS projects.

What cURL flags are converted to fetch features?

-H becomes headers, -d/--data-raw/--data-binary become body, -X sets method, -u becomes an Authorization header, -G moves data into the query string, -A/-e/-b map to User-Agent, Referer, and Cookie headers, and --json sets both JSON content type and body.