Skip to content
UseQR
ESC

↑↓ MOVE↵ OPEN48 PLACES

Developers & agents

Generate a QR code in Node.js

In Node, the qrcode npm package covers everything offline: QRCode.toFile for files, toDataURL for embedding, toString for SVG, and toFileStream to pipe PNG straight into an HTTP response. If you would rather not own an imaging dependency, fetch the keyless API and relay the bytes.

View as MarkdownPaste this page into any AI assistant — it is plain, portable Markdown.

The qrcode package

npm install qrcode gives you the ecosystem's standard server-side generator. Four output methods cover nearly every case:

import QRCode from "qrcode";

await QRCode.toFile("qr.png", "https://example.com", { margin: 4, width: 1024 });
const dataUrl = await QRCode.toDataURL("https://example.com");
const svg = await QRCode.toString("https://example.com", { type: "svg", margin: 4 });
const terminal = await QRCode.toString("hello", { type: "terminal" });

That last one prints a scannable code into stdout — handy for CLI tools that want to hand a URL to a phone. margin: 4 is the 4-module quiet zone; do not trim it.

Streaming into an HTTP response

toFileStream accepts any writable stream, and an HTTP response is one. No temp files, no buffering the whole image:

import http from "node:http";
import QRCode from "qrcode";

http.createServer((req, res) => {
  const data = new URL(req.url, "http://x").searchParams.get("data") ?? "hello";
  res.writeHead(200, {
    "Content-Type": "image/png",
    "Cache-Control": "public, max-age=31536000, immutable",
  });
  QRCode.toFileStream(res, data, { margin: 4, width: 512 });
}).listen(3000);

The immutable cache header is correct here because the same input always produces the same code — let browsers and CDNs keep it. The same idea in a framework context is on the Next.js page, and constraints for Lambda-style runtimes are in QR codes in serverless functions.

Batch generation

For a run of codes — one per order, per ticket, per asset — a plain loop is fine into the thousands, because qrcode is pure JavaScript with no native imaging binary:

import QRCode from "qrcode";

for (const { slug, url } of rows) {
  await QRCode.toFile(`codes/${slug}.svg`, url, { type: "svg", margin: 4 });
}

Write SVG for anything destined for print — it is smaller than PNG at print resolution and never pixelates. Scaling patterns, concurrency and file-naming discipline are covered in bulk QR generation at scale.

When to proxy the API instead

The keyless API earns its place when you want styling (module shapes, eye styles, colours) without writing renderer code, typed payload builders (/api/v1/wifi, /api/v1/upi) with server-side validation, or simply zero dependencies:

const res = await fetch(
  `https://useqr.app/api/v1/qr?data=${encodeURIComponent(url)}&size=1024&ec=Q`
);
await fs.promises.writeFile("qr.png", Buffer.from(await res.arrayBuffer()));

Generate locally when payloads are sensitive (credentials never belong in someone else's request logs) or when the network is off the table.

Close the loop: decode what you made

Rendering a matrix does not prove the output scans, especially once styling or logos are involved. One extra call closes the loop:

const report = await fetch(
  `https://useqr.app/api/v1/verify?data=${encodeURIComponent(url)}&color=6366f1`
).then((r) => r.json());
if (!report.scannable) throw new Error(report.issues.join("; "));

Reasoning and alternatives (zxing-wasm locally) in why verify that your QR code decodes.

FAQ

What is the standard QR library for Node.js?

The qrcode npm package. It is pure JavaScript, needs no native imaging dependency, and outputs files, data URLs, SVG strings and streams.

How do I return a QR code from an HTTP endpoint?

Set Content-Type to image/png and pass the response object to QRCode.toFileStream. Add an immutable cache header, since identical input always yields identical bytes.

Should I generate PNG or SVG on the server?

SVG for print and for anything that might be resized; PNG for fixed-size screen display and email clients. The qrcode package produces both.

How do I know the generated code actually scans?

Decode it back. Call GET /api/v1/verify with the same data and styling, or run zxing-wasm locally, and fail the job if the report says it is not scannable.

Try it — free, no signup

  • A free QR code API with no keyUseQR's REST API needs no signup, no API key and no SDK. GET /api/v1/qr?data=hello returns a PNG. The shortest form is /q/hello.png, which drops straight…
  • Generate a QR code in JavaScript and ReactFor a QR code in a browser or React app, either point an <img> at the keyless API — one line, no dependency — or use a client-side library such as qrcode…
  • Bulk QR generation at scaleGenerating hundreds to millions of QR codes: the batch API and its limits, local generation with worker pools, determinism as a caching strategy, and manifests.
  • QR codes in serverless functionsGenerating QR codes in Lambda, Cloudflare Workers and Vercel functions — bundle size, native dependency pitfalls, streaming, and when to skip the function entirely.