100% Private

QR Codes Explained: Complete Guide for Developers and Marketers

QR codes are simple on the surface and surprisingly deep underneath. This guide covers how they actually work—modules, error correction, encoding modes—and the practical decisions that determine whether your code scans reliably or fails in the field.

Anatomy of a QR Code

A QR code is a 2D matrix of black and white squares called modules. Not all modules carry data—several structural elements help scanners locate, orient, and decode the code reliably regardless of angle or partial damage.

Structural Elements

ElementLocationPurpose
Finder patternsThree cornersThree 7×7 squares that let cameras detect the code's presence and orientation in any direction
SeparatorsAround finder patternsWhite border isolating finder patterns from data modules
Timing patternsBetween top finder patternsAlternating black/white strips that establish the module grid coordinates
Alignment patternsLower-right area (Version 2+)Smaller square markers that correct for perspective distortion in larger codes
Format informationAdjacent to finder patternsEncodes the error correction level and mask pattern used
Data and ECC modulesRemaining areaThe actual encoded content plus error correction codewords
Quiet zoneOuter borderMinimum 4 modules of white space all around—scanners need this to detect code edges

The finder patterns are the most recognizable feature—those three identical squares in the corners. They're specifically designed so the scanner can detect the 1:1:3:1:1 black/white ratio from any scan angle.

QR vs. Traditional Barcodes

Feature1D BarcodeQR Code
Dimensions1D (horizontal lines)2D (matrix grid)
Data capacity~20 charactersUp to 7,089 digits
Data typesNumeric primarilyText, URLs, binary, Kanji
Error correctionNone7–30% recovery
Scan directionMust be alignedAny angle
Damage toleranceNoneReads even when partially obscured

Versions and Capacity

QR codes come in 40 versions. Version 1 is 21×21 modules. Each subsequent version adds 4 modules per side, so Version 40 is 177×177. Higher versions hold more data but produce physically larger codes that take longer to scan.

VersionSizeMax numeric (L)Max alphanumeric (L)Max bytes (L)
121×21412517
537×371549364
1057×57652395271
2097×972,0611,249858
40177×1777,0894,2962,953

The encoder selects the lowest version that fits your data. If you reduce the content length—say, by using a URL shortener—the encoder can use a smaller, faster-scanning version. For most URL-based QR codes, you'll land in Version 3–7.

Practical cap: Keep your QR code content under 100 bytes when possible. Larger codes scan more slowly, print less cleanly, and need to be physically larger to remain readable.

Encoding Modes

The encoder picks the most efficient mode based on your content. Using the wrong mode wastes capacity—a code in byte mode can hold significantly less than the same characters in numeric mode.

ModeCharactersBits per charBest for
Numeric0–93.3Phone numbers, product codes, serial numbers
Alphanumeric0–9, A–Z, space, $%*+-./:5.5Uppercase URLs, codes, short references
ByteAny UTF-8/ISO-8859-18Lowercase text, URLs with lowercase, most content
KanjiShift-JIS Japanese characters13Japanese text

The practical consequence: if you uppercase your URL, it can encode in alphanumeric mode and fit more data. But most modern encoders handle mixed-mode segments, switching between modes mid-content when it saves space.

// Effect of mode on capacity (same Version 5, Level M):
"1234567890123456789012345"  → Numeric mode   → fits in ~version 2
"HTTPS://TOOLSDOCK.COM"      → Alphanumeric   → more efficient than byte
"https://toolsdock.com"      → Byte mode      → lowercase forces byte mode

Masking

After encoding, the encoder applies one of 8 XOR mask patterns to the data area. The purpose: avoid large solid areas, regular patterns, or sparse regions that confuse scanners. The encoder evaluates all 8 masks and picks the one with the best score. This is automatic—you never need to think about it, but it explains why two identical-content QR codes from different generators may look slightly different.

Error Correction

QR codes use Reed-Solomon error correction—the same algorithm used on CDs and DVDs. It lets decoders reconstruct missing or corrupted data from the redundant codewords scattered through the data area.

LevelRecovery capacityData overheadWhen to use
L (Low)~7%MinimalClean digital displays, maximum data density
M (Medium)~15%ModerateGeneral purpose—most printed materials
Q (Quartile)~25%HigherIndustrial environments, outdoor signage
H (High)~30%HighestLogo overlay, harsh conditions, expected damage

Higher error correction means more of the code's area is dedicated to redundancy instead of data. For the same content, Level H produces a physically larger code than Level L. That's the tradeoff: robustness costs space.

Logo rule: Adding a logo to the center of a QR code works because the logo physically destroys the underlying modules—but error correction reconstructs what's missing. This only works reliably at Level H, and only if the logo covers less than 30% of the total area. Test with at least five different phones before printing.

Data Formats

QR codes are just containers for strings. Several URI schemes have become standard for triggering specific phone behaviors when scanned.

URL (most common)

https://toolsdock.com/code-generator/qr-code-generator/?utm_source=print

WiFi credentials

WIFI:T:WPA;S:OfficeNetwork;P:MyPassword123;H:false;;

# Parameters:
# T = Security type: WPA, WEP, or nopass
# S = Network SSID (name)
# P = Password
# H = Hidden network: true or false

Android 10+ and iOS 11+ handle this natively without any app. Scanning prompts the user to join.

vCard (contact)

BEGIN:VCARD
VERSION:3.0
N:Smith;Jane
FN:Jane Smith
ORG:Acme Corp
TEL:+15551234567
EMAIL:jane@acme.com
URL:https://acme.com
END:VCARD

Calendar event

BEGIN:VEVENT
SUMMARY:Product Launch
DTSTART:20260415T140000Z
DTEND:20260415T160000Z
LOCATION:Main Conference Hall
DESCRIPTION:Annual product launch event
END:VEVENT

Email, phone, SMS

mailto:contact@example.com?subject=Inquiry&body=Hello

tel:+15551234567

sms:+15551234567?body=I%20saw%20your%20sign

Geo location

geo:40.7128,-74.0060

TOTP (two-factor auth setup)

otpauth://totp/Example:alice@example.com?secret=JBSWY3DPEHPK3PXP&issuer=Example

This is the standard format used by authenticator apps when you scan a 2FA setup code.

Bitcoin payment

bitcoin:1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa?amount=0.001&label=Donation

Static vs. Dynamic QR Codes

StaticDynamic
Data storageEncoded directly in the codeShort URL that redirects to your destination
Changeable?No—fixed at creationYes—change destination without reprinting
Trackable?NoYes—scans, location, device type
Code sizeGrows with content lengthSmall and consistent (short URL)
Requires service?NoYes—a redirect service must stay live
PrivacyComplete—no trackingScan data collected by redirect service

Dynamic QR codes solve the biggest practical problem with printed materials: you can't reprint a thousand brochures if the URL changes. Point the short redirect at a new destination and every old printed code works. The tradeoff is dependency on a service staying operational.

Dead link risk: If the redirect service shuts down or you cancel your subscription, every printed code with that dynamic URL stops working. For permanent signage or print runs with long lifespans, static codes with stable URLs are safer.

Design and Scanning Reliability

Size guidelines

Viewing distanceMinimum code sizeTypical use
10 cm (4")2 cm (0.8")Business cards
30 cm (12")3 cm (1.2")Flyers, table tents, menus
1 m (3 ft)10 cm (4")Posters, window clings
5 m (16 ft)50 cm (20")Billboards, banners

Contrast

Dark modules on a light background. The scanner measures reflected light—low contrast means ambiguous readings. Black on white has a 21:1 contrast ratio. The minimum you can get away with is roughly 4:1.

Works well:
  Black on white (best)
  Dark navy on white
  Dark green on white
  Black on light yellow
Avoid:
  Red foreground (causes failures with some scanners)
  Orange or yellow modules on white
  Light gray on white
  Inverted (white on black) without thorough testing

Quiet zone

The quiet zone is the mandatory white border around the entire code. Minimum is 4 modules wide—roughly 10% of the total code size on each side. Printing text or graphics right up against the code's edge without quiet zone is the single most common reason professionally printed codes fail.

Adding a logo

  1. Set error correction to Level H before generating
  2. Keep the logo under 30% of total code area (width × height)
  3. Center it precisely—off-center logos can cover format information strips
  4. Add white padding around the logo so modules near it remain readable
  5. Test with at least 5 phones including older Android devices

File format for output

FormatBest forNotes
SVGAll print workScales to any size perfectly, edit in Illustrator or Inkscape
PDFPrint productionVector, print-ready, can embed fonts
PNGFixed-size digital useExport at 300+ DPI; lossless compression preserves sharp edges
JPEGNeverCompression blurs module edges and causes scan failures

Generating QR Codes Programmatically

JavaScript (browser)

// qrcode npm package — works in Node and browser via bundler
import QRCode from 'qrcode';

// PNG data URL for use in <img src>
const dataUrl = await QRCode.toDataURL('https://toolsdock.com', {
  errorCorrectionLevel: 'M',
  width: 300,
  margin: 2,
  color: { dark: '#000000', light: '#ffffff' }
});

// SVG string
const svg = await QRCode.toString('https://toolsdock.com', {
  type: 'svg',
  errorCorrectionLevel: 'M'
});

// Write to file (Node.js only)
await QRCode.toFile('./qrcode.png', 'https://toolsdock.com', {
  width: 400,
  errorCorrectionLevel: 'H'  // Use H if adding a logo afterward
});

Python

import qrcode
from qrcode.image.svg import SvgPathImage

# Basic PNG
qr = qrcode.QRCode(
    version=None,          # Auto-select smallest version that fits
    error_correction=qrcode.constants.ERROR_CORRECT_M,
    box_size=10,
    border=4,
)
qr.add_data('https://toolsdock.com')
qr.make(fit=True)

img = qr.make_image(fill_color='black', back_color='white')
img.save('qrcode.png')

# SVG output
qr_svg = qrcode.make('https://toolsdock.com', image_factory=SvgPathImage)
qr_svg.save('qrcode.svg')

# With custom colors (requires Pillow)
from qrcode.image.styledpil import StyledPilImage
from qrcode.image.styles.colormasks import SolidFillColorMask

img = qr.make_image(
    image_factory=StyledPilImage,
    color_mask=SolidFillColorMask(front_color=(0, 0, 128))  # Dark blue modules
)

Node.js batch generation

const QRCode = require('qrcode');
const fs = require('fs');

const codes = [
  { data: 'https://example.com/product/1', filename: 'product-1.png' },
  { data: 'https://example.com/product/2', filename: 'product-2.png' },
  { data: 'WIFI:T:WPA;S:StoreWifi;P:pass123;;', filename: 'wifi.png' },
];

const options = { errorCorrectionLevel: 'M', width: 300, margin: 2 };

for (const code of codes) {
  await QRCode.toFile(`./output/${code.filename}`, code.data, options);
  console.log(`Generated ${code.filename}`);
}

Real-World Use Cases

Restaurant menus

Post-pandemic, QR menus went from novelty to default in many restaurants. The practical advantage beyond hygiene: you can update prices or items without reprinting. Use a dynamic QR code pointing to your menu URL. Put it on table cards and the front window, not buried on a receipt.

WiFi sharing

Hotels, cafes, and offices print WiFi QR codes instead of writing passwords on whiteboards. The guest scans, phone joins automatically. No reading out "capital-P, lowercase-a, number-2..." Use the WIFI: format and set error correction to M or higher since these are often laminated.

Payments

Most payment QR codes work one of two ways: the merchant displays a QR code the customer scans (Stripe, PayPal), or the customer shows their payment app's QR code to a reader. The Bitcoin bitcoin: URI scheme and similar are used for crypto payments. UPI in India uses a standardized upi:// scheme.

Digital business cards (vCard)

Print a QR code on your physical card that encodes your full vCard. When scanned, the phone offers to add the contact directly. Much faster than typing. Keep the vCard data minimal—name, phone, email, URL—or the code becomes large and dense.

2FA setup

Every time you scan a QR code to set up an authenticator app (Google Authenticator, Authy, 1Password), you're scanning an otpauth://totp/ URI. The QR code just encodes that string. If you're building a 2FA system, generate QR codes with the standard TOTP URI and they'll work with all major authenticator apps.

Event tickets

Use a unique URL or encoded token per ticket. The scanner at the gate validates it server-side and marks it used. Don't encode all ticket data locally in the QR—a screenshot of someone else's ticket would work. The code should just be an opaque identifier that your system validates.

Asset tracking

Print QR codes on equipment, packages, or containers. Encode a URL pointing to the asset's record in your system. When the scanner scans it, they see current location, maintenance history, or check-out status. Version 1–3 codes are fine for short IDs, and they're small enough to print on adhesive labels.

Tools

QR Code Generator

Generate QR codes for URLs, WiFi, vCards, email, phone, and plain text. Download as PNG or SVG.

Generate QR Code
QR Code with Logo

Create branded QR codes with a logo in the center. Automatically sets Level H error correction.

Add Logo to QR
WiFi QR Generator

Generate a WiFi connection QR code from your network name and password.

WiFi QR Code
vCard QR Generator

Turn your contact details into a scannable QR code for digital business cards.

vCard QR Code

Quick Reference: QR Data Formats

TypeFormat
URLhttps://example.com
Emailmailto:you@example.com?subject=Hi
Phonetel:+15551234567
SMSsms:+15551234567?body=Hello
WiFiWIFI:T:WPA;S:SSID;P:pass;;
Geogeo:40.7128,-74.0060
TOTPotpauth://totp/Label?secret=BASE32&issuer=App
Bitcoinbitcoin:ADDRESS?amount=0.001

Last updated: March 2026. All QR code generation on ToolsDock happens in your browser—no data is sent to any server.

Privacy Notice: This site works entirely in your browser. We don't collect or store your data. Optional analytics help us improve the site. You can deny without affecting functionality.