A technical deep-dive into QR code structure, error correction levels, encoding modes, and generating QR codes in JavaScript.
QR (Quick Response) codes are two-dimensional barcodes invented by Denso Wave in 1994. Unlike traditional barcodes that store data horizontally, QR codes store data in both dimensions — allowing much more information in a small space.
A QR code can encode up to 4,296 alphanumeric characters or 7,089 numeric digits. In practice, most QR codes encode URLs between 30 and 150 characters.
Every QR code contains these elements:
■ ■ ■ ■ ■ ■ ■ · · · ■ · ■ ■ ■ ■ ■ ■ ■
■ · · · · · ■ · · · ■ · ■ · · · · · ■
■ · ■ ■ ■ · ■ · · ■ ■ · ■ · ■ ■ ■ · ■
↑ ↑ ↑
Finder Timing Format
Pattern Patterns Info
QR codes use Reed-Solomon error correction. Four levels trade data capacity for damage resilience:
| Level | Data Recovery | Use Case |
|---|---|---|
| L | ~7% | Clean digital displays, low-resolution screens |
| M | ~15% | General purpose (default for most uses) |
| Q | ~25% | Industrial labels, some physical damage expected |
| H | ~30% | Harsh environments, overlaid logos in center |
Practical tip: Use level M for web/digital use. Use level H only when you need to overlay a logo on the QR code, as the logo covers data that error correction must recover.
QR codes have four encoding modes that determine data density:
| Mode | Characters | Capacity (Version 1) |
|---|---|---|
| Numeric | 0–9 | 41 digits |
| Alphanumeric | 0-9, A-Z, space, $%*+-./: | 25 chars |
| Byte | Any UTF-8 | 17 bytes |
| Kanji | Japanese | 10 characters |
Most web URLs use byte mode since they contain lowercase letters not in the alphanumeric set.
The most popular library is qrcode (also called node-qr-code):
npm install qrcode
import QRCode from 'qrcode';
// Generate as data URL (for use in <img> src)
const dataUrl = await QRCode.toDataURL('https://heolab.com', {
errorCorrectionLevel: 'M',
width: 300,
margin: 4,
color: {
dark: '#000000',
light: '#ffffff',
},
});
// Generate to canvas element
const canvas = document.getElementById('qr-canvas');
await QRCode.toCanvas(canvas, 'https://heolab.com', { width: 300 });
// Generate SVG string
const svg = await QRCode.toString('https://heolab.com', { type: 'svg' });
// Server-side: write to file
await QRCode.toFile('/tmp/qr.png', 'https://heolab.com');
Keep URLs short. Shorter data = smaller QR code = easier to scan. If your URL is long, use a URL shortener before encoding.
Test before printing. Always test with multiple devices. Android and iOS built-in cameras behave differently in low contrast or small size.
Minimum size: 2cm × 2cm (0.8 inches) for reliable scanning from a normal distance. For print at 300 DPI, this means at least 236 × 236 pixels.
Contrast matters: High contrast between dark and light modules is essential. Never use light colors for dark modules — you can use brand colors, but keep contrast ratio above 4:1.
Add whitespace (quiet zone): The QR code spec requires a 4-module quiet zone on all sides. Most libraries add this by default.
You can overlay a logo on a QR code as long as it covers less than the error correction level allows:
// Generate QR with H correction (30% recovery) for logo overlay
const dataUrl = await QRCode.toDataURL(url, {
errorCorrectionLevel: 'H',
width: 400,
});
// Then use Canvas API to composite logo in center
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const qrImg = await loadImage(dataUrl);
const logo = await loadImage('/logo.png');
canvas.width = canvas.height = 400;
ctx.drawImage(qrImg, 0, 0, 400, 400);
const logoSize = 80; // Max ~20% of QR size
const offset = (400 - logoSize) / 2;
ctx.drawImage(logo, offset, offset, logoSize, logoSize);
Need a quick QR code without writing code? HeoLab's QR Code Generator creates QR codes instantly in your browser with custom colors, error correction, and PNG download — no server required.
QR codes are simple in concept but have rich technical depth. Understanding error correction levels, encoding modes, and size requirements helps you make the right trade-offs between capacity, reliability, and aesthetics.