QR codes are everywhere, but most developers treat them as a black box — scan, get URL, done. Understanding how they work makes you a better tool-user and opens up some genuinely useful applications.
What is a QR code?
QR (Quick Response) codes are 2D matrix barcodes invented by Denso Wave in 1994 for tracking vehicle parts. They encode data as a pattern of black and white squares arranged in a grid. Unlike 1D barcodes that only encode numbers along a single axis, QR codes encode data in two dimensions, allowing much higher data density.
A standard QR code can encode up to 4,296 alphanumeric characters or 7,089 numeric-only digits.
Anatomy of a QR code
Every QR code has the same structural elements:
Finder patterns — three square patterns in three corners. Their consistent shape lets scanners find and orient the code regardless of rotation or viewing angle.
Timing patterns — alternating black and white dots between the finder patterns. They help the decoder calculate the grid size.
Alignment patterns — smaller squares distributed through larger codes. They help correct distortion when the code is photographed at an angle.
Data area — the remaining modules (squares) encode the actual data.
Quiet zone — a white border around the entire code. Scanners need this margin to distinguish the code from its surroundings.
Error correction codewords — redundant data that allows partial damage to be recovered. There are four levels:
- L (Low) — can recover ~7% damage
- M (Medium) — ~15%
- Q (Quartile) — ~25%
- H (High) — ~30%
Higher error correction = larger QR code for the same data, but more resilient to damage.
What can QR codes encode?
QR codes encode text — but the encoding type affects how much data fits:
- Numeric: 0–9 only. Most compact. Used for phone numbers, ticket numbers.
-
Alphanumeric: 0–9, A–Z (uppercase only), space, and
$%*+-./:. More compact than binary for compatible strings. - Binary/byte: arbitrary bytes. Used for full UTF-8 text, URLs with lowercase letters.
- Kanji: optimised encoding for Japanese characters.
In practice, most scanners on modern smartphones can handle anything a QR code contains, including Unicode text. But if you want maximum compatibility, keep URLs short and ASCII-only.
Common QR code use cases
URLs — the most common use. Any URL works, but shorter URLs produce smaller codes that are easier to scan.
Contact cards (vCard/MeCard) — a specific format that creates a QR code your phone's camera app recognises as a contact to save.
Wi-Fi credentials — a format that connects a phone to Wi-Fi when scanned:
WIFI:S:MyNetworkName;T:WPA;P:MyPassword;;
Plain text — QR codes can encode any text. Useful for notes, keys, IDs.
Payment/crypto addresses — Bitcoin and most crypto wallets display QR codes to receive payments.
Generating QR codes in JavaScript
For browser-based generation, the qrcode library is lightweight and no-dependency:
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
<div id="qr"></div>
<script>
new QRCode(document.getElementById("qr"), {
text: "https://snappytools.app",
width: 256,
height: 256,
colorDark: "#000000",
colorLight: "#ffffff",
correctLevel: QRCode.CorrectLevel.H
});
</script>
For Node.js:
const QRCode = require('qrcode');
// To file
await QRCode.toFile('qr.png', 'https://snappytools.app');
// To SVG string
const svg = await QRCode.toString('https://snappytools.app', { type: 'svg' });
// To data URL (for embedding in HTML)
const dataUrl = await QRCode.toDataURL('https://snappytools.app');
Generating QR codes in Python
import qrcode
qr = qrcode.QRCode(
version=1, # 1=smallest, auto-scales up as needed
error_correction=qrcode.constants.ERROR_CORRECT_H,
box_size=10, # pixels per module
border=4, # quiet zone in modules
)
qr.add_data('https://snappytools.app')
qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white")
img.save("qr.png")
QR codes without writing code
If you just need a QR code for a URL, WiFi network, or text string, you can generate it in your browser without any code. The QR Code Generator supports URLs, WiFi credentials, plain text, and contact cards — generates the code as you type, with download as PNG.
Common design mistakes
Too much data — encoding a 200-character URL produces a dense code that requires a steady hand and good lighting to scan. Use a URL shortener for long URLs.
Too little quiet zone — placing the QR code flush against text or another image makes it unscannable. Always maintain a 4-module white border (4× the size of one module).
Low contrast — the code must be high contrast. Beige-on-white or light-grey-on-white will fail in poor lighting. Black-on-white is always safest.
Adding a logo without increasing error correction — putting a logo in the centre works because error correction can recover the obscured data — but only at level H (30%). If you embed a logo, set error correction to H.
Testing your QR codes
Always test generated QR codes before printing or deploying. Test with:
- A phone camera's native QR scanner (not an app)
- A different phone model
- From the expected scan distance
- Under realistic lighting conditions
Print a test batch and scan from a printout — screen reflections and resolution differences mean a code that scans fine on-screen may fail in print.
QR codes are deceptively simple at the use-it level. Understanding the error correction levels, data encoding modes, and design constraints takes you from "use a library" to "reason about what's actually possible" — which matters when you're embedding logos, printing at small sizes, or encoding non-ASCII text.
Top comments (0)