Why Generate QR Codes in JavaScript?

JavaScript is the only language that runs natively in both the browser and on the server (Node.js), which makes it uniquely versatile for QR code generation. You can generate codes entirely client-side — without any network request — preserving user privacy and eliminating server cost. Or you can generate at the server level during a build step, inside an API route, or as part of a serverless function.

For developers who need to go deeper into the underlying data structure before writing any generation code, our pillar guide on QR code technical specifications covers encoding modes, error correction mathematics, and the module grid in full detail.

JavaScript code editor showing QR code generation with a rendered QR output alongside
QR code generation in JavaScript — the same libraries work in the browser and in Node.js with minor differences.
Privacy Note

Client-side generation with qrcode.js or qr-code-styling happens entirely in the user's browser. The encoded string is never sent to a third-party server, making it the correct choice for sensitive payloads such as Wi-Fi passwords, authentication tokens, or internal identifiers.

Choosing Your Library

Three libraries cover the overwhelming majority of JavaScript QR generation needs. Each has a different scope and trade-off profile:

Library Environment Output Styling Best For
qrcode.js Browser (CDN or ESM) Canvas / <img> Basic Quick integration, no build step
qr-code-styling Browser (npm or CDN) Canvas / SVG / PNG Rich Branded codes, download buttons
node-qrcode Node.js (npm) PNG file / data URL / SVG string Moderate APIs, build pipelines, SSR
Side-by-side comparison of QR code output from qrcode.js, qr-code-styling, and node-qrcode
Typical output from each library — qrcode.js (left, plain), qr-code-styling (centre, styled with dots and gradient), node-qrcode (right, file output).

qrcode.js: Browser Basics

qrcode.js (npm: qrcodejs2 or qrcodejs) is a zero-dependency library that renders a QR code directly onto an HTML canvas element or into an <img> tag. It requires no build pipeline — a single script tag is enough.

Installation

HTML / CDN
<!-- Include from CDN, no npm required -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
npm
npm install qrcodejs2

Basic Canvas Rendering

JavaScript
// HTML: <div id="qrcode"></div>

const qr = new QRCode(document.getElementById('qrcode'), {
    text: 'https://www.generateonlineqr.com',
    width:  256,
    height: 256,
    colorDark:  '#1a1a1a',
    colorLight: '#ffffff',
    correctLevel: QRCode.CorrectLevel.M  // L | M | Q | H
});

The library appends a <canvas> element (and a fallback <img> for older browsers) inside the target div. correctLevel maps to the standard error correction levels — use H if you plan to overlay a logo. For the full breakdown of error correction levels and their trade-offs, see the technical specifications guide.

Updating the QR Code Dynamically

JavaScript
// Re-render with new content on user input
document.getElementById('input').addEventListener('input', (e) => {
    qr.makeCode(e.target.value);
});

qr-code-styling: Styled Output with PNG/SVG

qr-code-styling extends client-side generation with a rich styling API: dot shapes, rounded corners, gradient fills, embedded images, and custom finder patterns. It renders to a canvas or exports directly to PNG or SVG — making it the right choice when you need download functionality or branded output.

Installation

npm
npm install qr-code-styling

Styled Canvas Rendering

JavaScript (ESM)
import QRCodeStyling from 'qr-code-styling';

const qrCode = new QRCodeStyling({
    width:  300,
    height: 300,
    data:   'https://www.generateonlineqr.com',
    dotsOptions: {
        color: '#1a1a1a',
        type:  'rounded'   // 'square' | 'dots' | 'rounded' | 'classy' | 'classy-rounded' | 'extra-rounded'
    },
    backgroundOptions: {
        color: '#ffffff'
    },
    cornersSquareOptions: {
        type:  'extra-rounded'
    },
    qrOptions: {
        errorCorrectionLevel: 'M'
    }
});

// Append canvas to the DOM
qrCode.append(document.getElementById('canvas-container'));
Tip

Use type: 'dots' or 'rounded' for consumer-facing codes where aesthetics matter, and 'square' for any production context that requires maximum scanner compatibility. For a full comparison of module shape reliability, see the article on QR code styles and shapes.

node-qrcode: Server-Side Generation

node-qrcode (npm: qrcode) is the standard library for server-side QR generation in Node.js. It has no browser dependency, produces correct output in all Node environments, and supports writing to a file, returning a data URL, or generating an SVG string.

Installation

npm
npm install qrcode

Write to PNG File

Node.js (CommonJS)
const QRCode = require('qrcode');

QRCode.toFile(
    'output.png',
    'https://www.generateonlineqr.com',
    {
        errorCorrectionLevel: 'M',
        type:   'png',
        width:  512,
        margin: 2,
        color: {
            dark:  '#1a1a1aff',
            light: '#ffffffff'
        }
    },
    (err) => {
        if (err) throw err;
        console.log('QR code saved to output.png');
    }
);

Return Data URL (Promise API)

Node.js (ESM / async)
import QRCode from 'qrcode';

async function generateDataUrl(text) {
    try {
        const url = await QRCode.toDataURL(text, {
            errorCorrectionLevel: 'H',
            width: 400
        });
        return url; // 'data:image/png;base64,...'
    } catch (err) {
        console.error(err);
    }
}

Generate SVG String

Node.js
const svgString = await QRCode.toString(
    'https://www.generateonlineqr.com',
    { type: 'svg' }
);
// svgString is a complete <svg> element — embed directly in HTML or write to a .svg file
Browser demo showing a generated QR code with a download PNG and download SVG button below it
A minimal demo UI — text input, live QR preview rendered to canvas, and one-click PNG/SVG download buttons.

Need QR Codes Without Writing Code?

Our free online generator handles everything in your browser — choose styles, download PNG or SVG, no account needed.

Download as PNG or SVG

Both client-side libraries make download straightforward, but the mechanics differ slightly between PNG and SVG formats.

Download PNG from Canvas (qrcode.js or qr-code-styling)

JavaScript
// For qrcode.js — get the canvas element the library created
function downloadPNG() {
    const canvas = document.querySelector('#qrcode canvas');
    const link   = document.createElement('a');
    link.download = 'qrcode.png';
    link.href     = canvas.toDataURL('image/png');
    link.click();
}

Download PNG or SVG (qr-code-styling convenience method)

JavaScript
// qr-code-styling has a built-in download() method
document.getElementById('btn-download-png').addEventListener('click', () => {
    qrCode.download({ name: 'my-qr', extension: 'png' });
});

document.getElementById('btn-download-svg').addEventListener('click', () => {
    qrCode.download({ name: 'my-qr', extension: 'svg' });
});

Write SVG to File (node-qrcode)

Node.js
import QRCode from 'qrcode';
import fs      from 'node:fs/promises';

const svg = await QRCode.toString('https://example.com', { type: 'svg' });
await fs.writeFile('output.svg', svg, 'utf8');
console.log('SVG written successfully');
Format Guidance

Use SVG for any output that will be scaled (print, large-format display, vector design tools) — it remains sharp at any size. Use PNG for web embeds, email assets, and any context where a raster format is required. When building an API that serves QR codes to clients, returning a base64 PNG data URL is the most universally compatible choice.

For developers building a complete generation API rather than a one-off script, see our guide to the QR code generator API, which covers endpoint design, rate limiting, and format negotiation. If your backend stack uses Python instead of Node.js, the Python QR code generation guide covers qrcode and segno with equivalent code examples.

Quick-Start Checklist

1

Pick your environment. Browser-only project? Use qrcode.js (CDN, no build step) or qr-code-styling (npm, styled output). Node.js project or API? Use node-qrcode.

2

Set error correction level. Use M as a safe default. Upgrade to H if you're embedding a logo or using heavy module styling that may reduce contrast.

3

Set a minimum width of 256 px for screen use, 512 px for print assets. Small QR codes rendered at low resolution fail to scan on many devices.

4

Keep margin/quiet zone at 2–4 modules. All three libraries accept a margin parameter. Never crop this space — the scanner uses it to detect the code boundary.

5

Test on real devices before deploying. Scan the generated code with iPhone (native Camera), Android (Google Lens), and a third-party QR reader app. Test at the smallest size you'll use in production.

Frequently Asked Questions

qrcode.js is the most widely used client-side library — it requires no build step, works in any browser, and renders to a canvas or an img tag with a single function call. If you need styled output (dots, rounded modules, logos, gradients), qr-code-styling provides a richer API while still running entirely in the browser.

Call canvas.toDataURL('image/png') to get a base64 data URL, then create a hidden anchor element with its href set to that URL and its download attribute set to your desired filename. Programmatically clicking the anchor triggers the browser’s file-save dialog. The qr-code-styling library wraps this in a convenience download() method that works for both PNG and SVG.

Yes. The node-qrcode package (npm install qrcode) works in any Node.js environment and can write QR codes to a PNG file, return a data URL string, or output an SVG string — all without a DOM or canvas polyfill. It is the standard choice for server-side generation, including REST APIs, serverless functions, and build pipelines.

No. Client-side generation with qrcode.js or qr-code-styling happens entirely in the user’s browser — the encoded string never leaves the device and is not sent to any server. This makes client-side generation the privacy-preserving choice for sensitive payloads such as Wi-Fi credentials, personal URLs, or internal system identifiers.

Level M (15% correction) is a good default for most programmatic use cases — it balances data density with resilience. Use level H (30% correction) if you plan to overlay a logo on the QR code, as the logo will obscure part of the data modules. Use level L (7% correction) only when you need to maximise data density and the code will be scanned in ideal conditions.