The Standard HTTP Client — Same as the Browser
fetch in Node
Node 18+ ships a built-in fetch. Same API as the browser, no `axios` or `node-fetch` needed.
What you'll learn
- Make GET and POST requests
- Send/receive JSON
- Handle errors and timeouts
Node 18+ has the same fetch API browsers use. No more axios or
node-fetch for outbound HTTP — built-in works.
GET JSON
const res = await fetch("https://api.github.com/users/anthropics");
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
console.log(data.name); fetch returns a Response. Check res.ok (status 200–299) before
parsing.
POST JSON
const res = await fetch("https://api.example.com/users", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ name: "Ada", email: "ada@example.com" }),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const created = await res.json(); Headers + Auth
const res = await fetch(url, {
headers: {
"authorization": `Bearer ${token}`,
"user-agent": "my-app/1.0",
},
}); Timeouts
AbortSignal.timeout(ms) is the standard way:
try {
const res = await fetch(url, { signal: AbortSignal.timeout(5_000) });
} catch (err) {
if (err.name === "AbortError") console.error("timed out");
else throw err;
} Streams
Treat the response body as a stream for large downloads:
import { createWriteStream } from "node:fs";
import { Readable } from "node:stream";
const res = await fetch("https://example.com/huge.zip");
const stream = createWriteStream("huge.zip");
await Readable.fromWeb(res.body).pipe(stream); fetch body is a Web ReadableStream; Node has Readable.fromWeb
to convert.
File Uploads (multipart)
const form = new FormData();
form.append("file", new Blob([fileContent]), "report.pdf");
form.append("title", "Q3");
await fetch("https://api.example.com/upload", { method: "POST", body: form }); FormData and Blob are global in Node 18+. No form-data lib
needed.
When You Outgrow fetch
For complex needs (HTTP/2, connection pooling, retries),
undici is what powers Node’s
built-in fetch — you can use it directly for advanced cases.