How QR Codes Work: Encoding, Error Correction, and Practical Uses
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:
| Mode | Character Set | Data Density |
|---|---|---|
| Numeric | Digits 0–9 | Highest |
| Alphanumeric | 0–9, A–Z, space, $%*+-./: | High |
| Byte | Raw 8-bit data (typically ISO-8859-1 or UTF-8) | Moderate |
| Kanji | Shift JIS double-byte characters | Moderate |
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:
| Level | Name | Recovery Capacity | Data Capacity Impact |
|---|---|---|---|
| L | Low | ~7% | Highest data capacity |
| M | Medium | ~15% | Good balance |
| Q | Quartile | ~25% | Reduced capacity |
| H | High | ~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)
| Mode | Maximum Characters |
|---|---|
| Numeric | 7,089 |
| Alphanumeric | 4,296 |
| Byte | 2,953 |
| Kanji | 1,817 |
At the highest error correction level (H), these numbers drop significantly:
| Mode | Maximum Characters (Level H) |
|---|---|
| Numeric | 1,273 |
| Alphanumeric | 771 |
| Byte | 531 |
| Kanji | 326 |
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.