Skip to content

Render PNG in Node.js

Use this when you need raster image bytes in Node.js, such as a file saved to disk, an API response, a downloadable asset, an email attachment, or any integration that expects PNG image bytes.

import {qrcode} from '@qrcodesdk/core';
import {PNGQRCodeRenderer} from '@qrcodesdk/node';
const png = qrcode('https://qrcodesdk.dev').render(PNGQRCodeRenderer());

The returned value is a Node.js Buffer containing PNG image bytes.

You can customize the PNG output by passing styling options to PNGQRCodeRenderer.

import {qrcode} from '@qrcodesdk/core';
import {PNGQRCodeRenderer} from '@qrcodesdk/node';
const png = qrcode('https://qrcodesdk.dev').render(
PNGQRCodeRenderer({
size: 8,
margin: 4,
colors: {
colorDark: '#111827',
colorLight: '#ffffff',
},
}),
);
Option Type Default Description
size number 5 Pixel size of each QR module.
margin number 4 Quiet-zone margin around the QR code, in modules.
colors.colorDark string '#000000' Color used for dark QR modules.
colors.colorLight string '#ffffff' Background color.

Colors must be 6-digit hex values such as '#000000', '#ffffff', or '#111827'.

import {writeFile} from 'node:fs/promises';
import {qrcode} from '@qrcodesdk/core';
import {PNGQRCodeRenderer} from '@qrcodesdk/node';
const png = qrcode('https://qrcodesdk.dev').render(PNGQRCodeRenderer());
await writeFile('qrcode.png', png);
import express from 'express';
import {qrcode} from '@qrcodesdk/core';
import {PNGQRCodeRenderer} from '@qrcodesdk/node';
const app = express();
app.get('/qrcode.png', (_req, res) => {
const png = qrcode('https://qrcodesdk.dev').render(PNGQRCodeRenderer());
res.type('image/png').send(png);
});
app.listen(3000);
import {serve} from '@hono/node-server';
import {Hono} from 'hono';
import {qrcode} from '@qrcodesdk/core';
import {PNGQRCodeRenderer} from '@qrcodesdk/node';
const app = new Hono();
app.get('/qrcode.png', (c) => {
const png = qrcode('https://qrcodesdk.dev').render(PNGQRCodeRenderer());
return c.body(png, 200, {
'Content-Type': 'image/png',
});
});
serve({
fetch: app.fetch,
port: 3000,
});

The PNG renderer generates:

  • A square PNG image
  • One pixel block per scaled QR module
  • A solid background using colors.colorLight
  • Dark modules using colors.colorDark
  • Fully opaque pixels
  • A Node.js Buffer

The final image size is calculated as:

const imageSize = size * (moduleCount + 2 * margin);

For example, a QR matrix with 21 modules, size: 8, and margin: 4 produces:

8 * (21 + 2 * 4) = 232

So the output PNG is 232 x 232 pixels.