Dev Utilities·6 min read·By the StackUtils Team

How QR Codes Work: Encoding, Error Correction, and Generation

QR codes are everywhere, but few developers know what's actually inside them. This guide explains the data encoding layers, error correction levels, version sizes, and how to generate QR codes programmatically.

What Is a QR Code?

QR (Quick Response) codes were invented in 1994 by Denso Wave, a Toyota subsidiary, to track automotive parts. Unlike traditional barcodes that store data in one dimension (horizontal bars), QR codes store data in two dimensions — the black and white modules arranged in a square grid.

This 2D structure lets QR codes store significantly more data: up to 7,089 numeric characters or 4,296 alphanumeric characters, compared to ~20 characters for a typical barcode.

The Anatomy of a QR Code

1

Finder Patterns

The three square boxes in the corners (top-left, top-right, bottom-left). Scanners use these to detect the QR code's position, size, and orientation — regardless of angle.

2

Alignment Pattern

A smaller square in the bottom-right area (absent in small version 1 codes). Helps correct perspective distortion when scanning at an angle.

3

Timing Patterns

Alternating black/white modules running between the finder patterns. Help the scanner calculate the module grid coordinates.

4

Format Information

Two bands adjacent to the finder patterns that encode the error correction level and mask pattern used — read first so the decoder knows how to interpret the rest.

5

Data and Error Correction Modules

The remaining grid area. Stores the actual encoded data interleaved with Reed-Solomon error correction codewords.

6

Quiet Zone

A mandatory white border (4 modules wide) surrounding the entire code. Without it, scanners may fail to locate the finder patterns.

Data Encoding Modes

The encoder chooses the most space-efficient mode based on the content:

ModeCharsetBits/charMax chars (v40-H)
Numeric0–93.37,089
Alphanumeric0–9, A–Z, space, $%*+-./:5.54,296
ByteISO 8859-1 / UTF-882,953
KanjiShift JIS characters131,817

URLs are encoded in Byte mode (UTF-8). Tip: using uppercase letters in URLs allows Alphanumeric mode, which is 27% more efficient — producing a less dense QR code that's easier to scan.

Error Correction Levels

QR codes use Reed-Solomon error correction. This is why a QR code with a logo in the middle still scans — the missing data can be reconstructed.

L (Low)Recovers ~7% damage

Smallest QR code. Use when the code will be displayed cleanly on a screen.

M (Medium)Recovers ~15% damage

Good balance. Default for most generators.

Q (Quartile)Recovers ~25% damage

Useful for industrial labels that may get dirty or scratched.

H (High)Recovers ~30% damage

Use when embedding a logo or the code will be physically damaged. Largest code size.

Versions and Size

A QR code version refers to its size, not a generation of the standard. Version 1 is a 21×21 module grid; each version increment adds 4 modules per side, up to version 40 (177×177 modules).

The encoder automatically selects the smallest version that fits your data at your chosen error correction level. Shorter URLs → smaller, easier-to-scan codes.

Generating QR Codes Programmatically

// JavaScript: qrcode package
import QRCode from 'qrcode';

// Generate as PNG data URL
const dataUrl = await QRCode.toDataURL('https://stackutils.dev', {
  errorCorrectionLevel: 'M',
  width: 256,
  margin: 4,
});

// Generate as SVG string
const svg = await QRCode.toString('https://stackutils.dev', {
  type: 'svg',
  errorCorrectionLevel: 'H', // High: for logos embedded in center
});

// Python: qrcode package
import qrcode
qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_M)
qr.add_data('https://stackutils.dev')
qr.make(fit=True)
img = qr.make_image(fill_color='black', back_color='white')
img.save('qr.png')

QR Code Best Practices

  • Use a short URL. Shorter data = smaller code = easier scan. Use a URL shortener for long URLs.
  • Use HTTPS. Some scanners warn on HTTP URLs.
  • Use H error correction when adding a logo — the logo obscures data that the error correction must recover.
  • Maintain the quiet zone. Never crop it or place text too close to the code.
  • Test before printing. Scan with multiple devices and apps. Print a test sheet first.
  • Minimum print size is ~2cm × 2cm for reliable scanning at arm's length.

Generate a QR code in seconds

Enter any URL, text, or data. Choose error correction level and download as PNG or SVG — no account needed.

Open QR Code Generator →