cURL to Node.js

Convert a cURL command into a Node.js fetch call.

cURL Command
Node.js (fetch) Output
Node.js (fetch) code appears here

Related Tools

Documentation

What is curl-to-Node?

This tool converts a curl command into a Node.js script that uses the built-in fetch API — the same fetch signature browsers use, available globally in Node 18+ without installing axios, node-fetch, or any other package.

How it works

The curl command is tokenized and parsed into method, url, headers, body, form fields, and auth. Each maps onto fetch's second argument: method, a headers object, and a body string taken verbatim from -d/--data — never re-parsed as JSON and re-serialized, so the exact bytes curl would send are preserved. -u user:pass is the one flag that needs a small computation rather than a straight mapping: fetch has no native "basic auth" option, so the generator emits Buffer.from('user:pass').toString('base64') at the top of the script and injects it into an Authorization header built from a template literal (Basic plus the credentials) — computed at runtime rather than baked in as a precomputed string, since Buffer is a Node global available wherever the script actually executes.

Features

  • Zero-install output — uses global fetch, no npm install required
  • Body passed through as a raw string, not re-encoded
  • -u Basic Auth computed via Buffer.from(...).toString('base64') at runtime
  • -F/--form uploads become a FormData instance, with file fields stubbed for you to attach real bytes
  • Uses top-level await, so it runs directly as an ES module without wrapping in an async function

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:

const credentials = Buffer.from('admin:s3cret').toString('base64');

const response = await fetch('https://api.example.com/v1/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Basic ${credentials}`,
  },
  body: '{"username":"admin","remember":true}',
});

const data = await response.text();
console.log(response.status, data);

Common errors

Top-level await only works in an ES module context — either a file with a .mjs extension, or a "type": "module" entry in package.json. In a plain CommonJS .js file you'll get a syntax error and need to wrap the code in an async function. Also, running the output on Node < 18 fails with "fetch is not defined" — either upgrade Node or install node-fetch and add the import.

Best practices

Check response.ok before trusting the body — unlike some other HTTP clients, fetch doesn't throw on 4xx/5xx status codes, only on network failures. Wrap the call in a try/catch for those network-level errors, and avoid logging the raw credentials variable anywhere in production logs.

Frequently Asked Questions

Does this need a package like axios or node-fetch?

No — fetch has been built into Node.js since v18 with no extra install, so the generated code works out of the box on any reasonably current Node version.

What Node version is required?

Node 18 or later, since that's when global fetch and FormData landed without a flag. If you're on an older Node version, install node-fetch or axios and adapt the call — the options object (method, headers, body) maps over directly.

How is Basic Auth handled?

The generated code computes the base64 credentials at runtime with Buffer.from(...).toString('base64'), rather than hardcoding a precomputed value — Buffer is a Node global, available wherever this generated code actually runs.

Does it support file uploads via -F?

Non-file fields are appended directly to a FormData instance. File fields include a TODO comment, since attaching real file bytes needs your filesystem (fs.readFileSync + Blob) which the generator can't access from your browser.