How QR Codes Work: Encoding, Error Correction, and Practical Uses

CodeKit
qr-codeencodingbarcode

What Is a QR Code?

A QR (Quick Response) code is a two-dimensional barcode invented in 1994 by Masahiro Hara at Denso Wave, a Japanese automotive company. Originally designed to track car parts during manufacturing, QR codes have become ubiquitous—appearing on business cards, restaurant menus, payment terminals, and advertisements.

Unlike traditional one-dimensional barcodes that encode data as parallel lines of varying widths, QR codes encode data in a grid of black and white squares (called modules) arranged in a square pattern. This two-dimensional structure allows QR codes to store far more data—up to 7,089 numeric digits compared to a standard barcode’s 20 characters.

You can generate QR codes for any text or URL using the QR Code Generator on CodeKit.

QR Code Structure

A QR code is more than a random grid of squares. It has a well-defined structure with several functional regions:

Finder Patterns

The three large squares in the corners (top-left, top-right, bottom-left) are the most recognizable feature. They allow a scanner to detect the QR code’s position, orientation, and size regardless of the angle at which it’s viewed. Each finder pattern is a 7×7 module square-within-a-square-within-a-square.

Alignment Patterns

Smaller concentric squares that help the decoder correct for distortion when the QR code is printed on a curved surface or photographed at an angle. Version 1 QR codes have no alignment patterns; higher versions have more.

Timing Patterns

Alternating black and white modules that run between the finder patterns. They help the decoder determine the size of the module grid.

Format Information

Two strips of modules near the finder patterns that store the error correction level and the data mask pattern. This information is decoded first so the rest of the data can be read correctly.

Data and Error Correction Modules

The remaining area stores the actual encoded data and the error correction codewords. Data is written in a zigzag pattern starting from the bottom-right corner.

Quiet Zone

A mandatory blank border (at least 4 modules wide) around the QR code that separates it from surrounding content. Without a quiet zone, scanners may fail to detect the code.

Encoding Modes

QR codes support four encoding modes, each optimized for different types of data:

ModeCharacter SetData Density
NumericDigits 0–9Highest
Alphanumeric0–9, A–Z, space, $%*+-./:High
ByteRaw 8-bit data (typically ISO-8859-1 or UTF-8)Moderate
KanjiShift JIS double-byte charactersModerate

Why Modes Matter

The encoding mode directly affects how much data fits in a given QR code size. Numeric mode packs about 3 digits into 10 bits, while byte mode uses a full 8 bits per character. If your data is purely numeric, using numeric mode lets you store roughly 2.5 times more data than byte mode in the same space.

Most QR code generators automatically detect the optimal mode, but if you’re generating codes programmatically, specifying the mode can help:

// Using a QR code library (e.g., qrcode)
import QRCode from 'qrcode';

// The library auto-detects the best encoding mode
await QRCode.toDataURL('1234567890');     // Numeric mode
await QRCode.toDataURL('HELLO WORLD');    // Alphanumeric mode
await QRCode.toDataURL('Hello, World!');  // Byte mode (lowercase + punctuation)

Error Correction Levels

One of the most remarkable features of QR codes is built-in error correction. Based on Reed-Solomon error correction, a QR code can be read correctly even when part of it is damaged, dirty, or obscured.

There are four error correction levels:

LevelNameRecovery CapacityData Capacity Impact
LLow~7%Highest data capacity
MMedium~15%Good balance
QQuartile~25%Reduced capacity
HHigh~30%Lowest data capacity

How Reed-Solomon Works

Reed-Solomon encoding adds redundant mathematical data (error correction codewords) alongside the actual data. When the decoder reads the QR code, it uses these redundant codewords to detect and correct errors—up to the recovery capacity of the chosen level.

At level H, you can cover up to 30% of the QR code and still recover the full data. This is why QR codes can be customized with logos in the center—the error correction compensates for the obscured area.

Choosing the Right Level

  • Level L: Use when the QR code will be displayed in a clean, controlled environment (e.g., digital screens, printed labels)
  • Level M: The default for most use cases—good balance of durability and data capacity
  • Level Q: Use when the code might be partially obscured or printed on rough surfaces
  • Level H: Use when you need to embed a logo, or the code will be exposed to significant wear (e.g., outdoor signage, product packaging)
// Specifying error correction level
import QRCode from 'qrcode';

const options = {
  errorCorrectionLevel: 'H'  // Use High to allow logo overlay
};

await QRCode.toDataURL('https://example.com', options);

Data Capacity

The amount of data a QR code can hold depends on three factors: the version (size), the encoding mode, and the error correction level.

QR Code Versions

QR codes come in 40 versions. Version 1 is a 21Ă—21 module grid; each subsequent version adds 4 modules per side, up to Version 40 at 177Ă—177.

Maximum Data Capacity (Version 40, Level L)

ModeMaximum Characters
Numeric7,089
Alphanumeric4,296
Byte2,953
Kanji1,817

At the highest error correction level (H), these numbers drop significantly:

ModeMaximum Characters (Level H)
Numeric1,273
Alphanumeric771
Byte531
Kanji326

Practical Limits

While Version 40 can hold thousands of characters, such large QR codes are difficult to scan. In practice, keep your data under 300 bytes for reliable scanning across all devices. If you need to encode more data, consider encoding a URL that points to the content instead.

Practical Use Cases

URLs and Marketing

The most common use case. A QR code on a poster, flyer, or business card links directly to a website:

https://example.com/promo/summer2025

Tip: Use a short URL or a redirect service to keep the QR code simple and scannable.

Payments

QR code payments are dominant in many countries. The code encodes payment details (merchant ID, amount, currency) that the customer’s banking app scans and processes.

Wi-Fi Network Sharing

QR codes can encode Wi-Fi credentials in a standard format:

WIFI:T:WPA;S:MyNetwork;P:MyPassword;;

Scanning this code automatically connects the device to the network—no manual entry needed.

vCard Contact Information

Embed contact details in a standard vCard format so scanning the code adds a contact to the phone:

BEGIN:VCARD
VERSION:3.0
N:Smith;John
TEL:+1234567890
EMAIL:john@example.com
END:VCARD

Two-Factor Authentication (TOTP)

Authenticator apps scan QR codes that encode TOTP secrets in a standard otpauth:// URI format. This is how you set up Google Authenticator, Authy, and similar apps.

Inventory and Asset Tracking

The original use case—encoding serial numbers, part numbers, or location codes on labels attached to physical items.

Best Practices for QR Code Generation

1. Keep Data Short

Longer data means larger, denser QR codes that are harder to scan. Use URL shorteners for links and avoid unnecessary whitespace in the encoded content.

2. Use Sufficient Error Correction

Level M is a safe default. If you plan to overlay a logo, use Level H and keep the logo under 10% of the total area.

3. Ensure Adequate Size and Contrast

A QR code should be at least 2×2 cm (about 0.8×0.8 inches) when printed. The contrast between the dark and light modules must be strong—black on white is ideal. Avoid using low-contrast color combinations.

4. Test on Multiple Devices

Older phone cameras may struggle with small or dense QR codes. Always test your generated codes on at least a few different devices before printing.

5. Include a Quiet Zone

Never place text, images, or other elements within the quiet zone (the blank border around the code). Scanners need this space to detect the code boundaries.

Conclusion

QR codes are a clever blend of information theory and practical engineering. The structured layout with finder patterns enables fast detection from any angle, the encoding modes optimize data density for different content types, and the Reed-Solomon error correction makes QR codes remarkably resilient to damage. Understanding these internals helps you generate codes that are compact, scannable, and reliable.

To create QR codes for URLs, text, Wi-Fi credentials, or any other data, try the QR Code Generator on CodeKit—it generates codes instantly in your browser with adjustable error correction levels and downloadable output.