VoidForge

Command Palette

Search for a command to run...

DeveloperJuly 19, 20265 min read

How QR Codes Work (and How to Generate Them)

QR codes are everywhere — payments, menus, boarding passes. Here's how they encode data, why they survive damage, and how to make your own.

VF
VoidForge Team
July 19, 2026
D

What is a QR code, really?

A QR (Quick Response) code is a 2D matrix barcode invented by Denso Wave in 1994 for tracking car parts. Unlike a 1D barcode (the vertical stripes on a cereal box), a QR code stores data in two dimensions — both horizontal and vertical — which means it can hold 100× more information in the same area.

A standard QR code holds:

  • Up to 7,089 numeric characters
  • Up to 4,296 alphanumeric characters
  • Up to 2,953 bytes of binary data
  • Up to 1,817 Kanji characters

Plenty for a URL, a vCard, a Wi-Fi credential, or a small payload.

Anatomy of a QR code

Look at any QR code and you'll see consistent structural elements:

  • Three large squares in the corners (finder patterns) — these tell the scanner "I'm a QR code, here's my orientation."
  • One smaller square near the fourth corner (alignment pattern) — helps with skew correction.
  • Timing patterns — alternating black/white modules between finders, used to calibrate the module grid.
  • Format information — small bits near finders encoding the error-correction level and mask pattern.
  • Data and error-correction modules — the rest of the code, encoded in a specific zig-zag pattern.
  • Quiet zone — a blank margin around the code, at least 4 modules wide, so scanners can find the edges.

How data gets encoded

  1. Pick the encoding mode. QR supports numeric, alphanumeric, byte, and Kanji modes. Pick the most efficient one for your data — numeric mode packs three digits into 10 bits, much denser than byte mode.

  2. Convert data to a bit stream. Each character becomes its mode-specific bits.

  3. Add error correction. QR uses Reed-Solomon error correction — the same math that makes CDs scratch-tolerant. There are four levels:

    • L — ~7% recovery
    • M — ~15% recovery (most common default)
    • Q — ~25% recovery
    • H — ~30% recovery

    Higher recovery means more redundancy, larger codes, but more tolerance for damage. A code with level H can lose 30% of its modules and still scan.

  4. Apply a mask pattern. QR codes can have large blocks of same-color modules that confuse scanners. The spec defines 8 mask patterns; the encoder tries each, scores the result, and picks the one that best breaks up solid regions.

  5. Lay out the modules. The data + error correction bits are written into the matrix in a zig-zag pattern, skipping the finder and timing patterns.

Why QR codes are so robust

Three reasons:

  • Reed-Solomon error correction. Even with damage, dirt, or partial obstruction, the math can reconstruct missing data.
  • Masking. No large solid regions means scanners can reliably detect module boundaries.
  • Finder patterns. Three corner squares make orientation detection trivial — scan from any angle, the code still works.

This is why a QR code on a crumpled flyer, a dirty menu, or a partially-peeled sticker still scans. It's also why you can brand a QR code by overlaying a logo in the center — the error correction handles the lost modules.

What QR codes can encode

Far more than URLs:

  • URLs — the most common, opens in a browser.
  • Plain text — notes, IDs, codes.
  • vCard — contact info that imports into a phone.
  • Wi-Fi credentialsWIFI:S:MySSID;T:WPA;P:password;; prompts the phone to join the network.
  • Email / SMS / phonemailto:, sms:, tel: URIs.
  • Geo coordinatesgeo:lat,lng opens Maps.
  • Calendar events — iCal data, adds to calendar.
  • App store links — for installs.
  • Crypto addresses — for payments.

How to generate a QR code

The easiest way: use the QR Code Generator. Pick a size, choose foreground and background colors, enter your data, download a PNG.

For developers, the typical approach is the qrcode npm package:

import QRCode from "qrcode";

// Generate a data URL
const dataUrl = await QRCode.toDataURL("https://voidforge.sbs", {
  width: 512,
  margin: 2,
  color: { dark: "#1a1a2e", light: "#ffffff" },
  errorCorrectionLevel: "M",
});

// Generate to a canvas
const canvas = document.querySelector("canvas");
await QRCode.toCanvas(canvas, "https://voidforge.sbs", { width: 512 });

Tips for reliable QR codes

  • Use level M error correction for general use, H if the code will be printed on something that might get damaged.
  • Keep contrast high. Dark on light or light on dark. Don't use medium-gray on light-gray.
  • Don't invert colors without testing — some scanners don't handle inverted codes.
  • Don't make them too small. A rule of thumb: 10× the data-density in millimeters. A URL with 30 characters should be at least 30 mm wide on print.
  • Always test with multiple phones before printing 10,000 flyers.
  • Don't link to a tracking URL that redirects — QR scanners cache poorly and redirects add latency. Link directly to the destination.

QR codes vs other 2D barcodes

  • Data Matrix — smaller for tiny payloads, common in electronics marking.
  • Aztec — used on boarding passes, no quiet zone needed.
  • PDF417 — stacked linear, used on driver's licenses.

For consumer-facing applications, QR is the right default — every modern phone camera scans them natively without an app.

Conclusion

QR codes are an elegant piece of 1990s engineering that found new life in the smartphone era. The math behind them — Reed-Solomon, masking, finder patterns — is what makes them survive dirty menus and crumpled flyers. Generate your own with the QR Code Generator and start embedding URLs, Wi-Fi credentials, or contact cards in your physical materials.

Tags:#qr code#encoding#developer#how-it-works

Explore more tools

VoidForge ships 80+ free, private, browser-based tools. No signups, no uploads, no watermarks.

Browse all tools

Related articles