QR Codes for Developers: Error Correction, SVG vs PNG, and the Math Inside
QR codes had a brief moment of being a marketing punchline ("scan to enter our sweepstakes") and then COVID rehabilitated them. By 2026 they're permanent infrastructure: restaurant menus, payment links, MFA setup, Wi-Fi sharing, package tracking. Most QR codes are generated by someone who clicked "make me a QR code" and shipped the result.
For 95% of cases, that's fine. For the other 5% — large prints, branded codes, codes that need to survive being torn or smudged, there are knobs worth knowing about.
What's actually in a QR code
A QR code is a 2D matrix barcode. Black and white squares (modules) encode data:
- The three big squares in the corners are finder patterns: they help the scanner orient the code regardless of rotation.
- The smaller square in the bottom-right is an alignment pattern for skew correction.
- The dotted lines between finder patterns are timing patterns for module size.
- The rest is data + error correction codes.
The scanner reads the modules, decodes the data using Reed-Solomon error correction, and gets the original payload. It can read codes that are partially obscured, rotated, smudged, or printed on a curved surface, within limits.
Sizes and capacities
QR codes come in versions 1 to 40, where higher version = bigger code = more data:
| Version | Modules | Max bytes (high error) |
|---|---|---|
| 1 | 21x21 | 7 |
| 5 | 37x37 | 50 |
| 10 | 57x57 | 174 |
| 20 | 97x97 | 535 |
| 40 | 177x177 | 1,273 |
For most use cases (URLs, contact info), version 5-10 is plenty. The generator picks the smallest version that fits your data.
QR Code Generator auto-selects the version. You can adjust the resolution of the output image without changing the QR's information density.
Error correction levels
This is the most important knob. QR codes have four levels:
| Level | Recovery | Module overhead |
|---|---|---|
| L (low) | ~7% | Smallest code |
| M (medium) | ~15% | Default |
| Q (quartile) | ~25% | Bigger |
| H (high) | ~30% | Biggest |
"Recovery" means: how much of the code can be obscured / damaged before it stops scanning. Higher levels add more redundancy, which means a bigger code for the same data.
When to use which level:
- L: clean digital displays, screens. No physical wear.
- M: default. Good for most printed materials.
- Q: printed signage, restaurant menus, anywhere the code might get scuffed.
- H: high-stakes scenarios: large outdoor prints, codes with logos in the middle (the logo replaces ~25% of the code), packaging that gets squished.
For a QR code with a logo overlay (which is a common branding choice), always use level H. The logo covers data; high error correction makes up for it.
SVG vs PNG
Two output formats matter:
PNG: raster image. Pixel-perfect at one size. Looks bad if scaled up beyond its native resolution.
SVG: vector. Scales to any size without quality loss. Smaller file size for high-resolution prints.
Use SVG when:
- Printing at any size larger than 5cm × 5cm
- Embedding in another vector format (PDFs, business cards, logos)
- The code will be displayed at multiple sizes (responsive web)
Use PNG when:
- Displaying at exactly one fixed size
- The destination doesn't render SVG (some legacy POS systems)
- You want a simple raster file
For digital use, default to SVG. For ad-hoc social media posts, PNG is fine.
URL design for QR codes
A QR code is a payload. For web URLs, what payload makes sense?
Don't put a long URL in the QR code itself
A 200-character URL forces a denser, harder-to-scan code. Worse, you can't change where the QR points without reprinting.
Use a short redirect URL
https://yoursite.com/q/abc123
The short URL contains a tracking ID. Your server resolves abc123 to the actual destination. Now you can:
- Change the destination without reprinting. The QR is dynamic.
- Track scans per QR code (when, where, what device).
- A/B test destinations.
- Include UTM params without bloating the QR.
This is what every URL shortener does (bit.ly, tinyurl). For internal use, host your own.
Avoid dynamic content in the URL
❌ https://yoursite.com/menu?date=2026-05-09&table=12&user=...
✅ https://yoursite.com/menu/12
The URL embedded in the QR should be stable. Anything dynamic should be derived server-side from the URL path.
Special QR types
QR codes can encode more than URLs. Some standardized types:
Wi-Fi credentials
WIFI:T:WPA;S:MyNetwork;P:my-password;;
Phones recognize this and prompt to join the network. Useful for guest networks, trade shows.
mailto:contact@example.com?subject=Hello&body=From%20your%20QR
Pre-fills an email when scanned.
Phone
tel:+84901234567
Initiates a call.
Geolocation
geo:21.0285,105.8542
Opens map app at coordinates.
Calendar event
BEGIN:VEVENT
SUMMARY:Conference 2026
DTSTART:20260601T090000
DTEND:20260601T170000
LOCATION:Hanoi
END:VEVENT
Adds an event to the user's calendar.
Authentication (TOTP)
otpauth://totp/Service:user@example.com?secret=ABC123&issuer=Service
The 2FA setup QR codes you see, they encode this URL. We covered the protocol in detail in TOTP and 2FA: How 6-Digit Codes Work.
Common mistakes
Quiet zone too small
QR specs require 4 modules of white space around the code (the "quiet zone"). If you crop the code tight, scanners can fail.
The fix: when designing layouts, leave whitespace around the QR. Don't print directly against another graphic.
Inverted colors
QR codes are typically black-on-white. Scanners assume this. Light-on-dark codes (e.g., white code on black background) fail on many scanners, especially older ones. Modern phones handle inversion, but older POS scanners may not.
If you must invert for branding reasons: test on multiple devices, and consider including a "scan" instruction.
Logo overlay too big
If you put a logo in the center of the QR, it covers data. Stay under 25% of the code area, and use error correction level H. Test before printing.
Tiny print sizes
A QR code printed at 1cm × 1cm requires a high-resolution camera held very close. Minimum reliable size: 2cm × 2cm for a phone camera. For "across the room" scanning (e.g., on a poster), aim for 5cm × 5cm or more.
For very small codes (medical bottles, electronic components), use Micro QR (a different barcode standard with smaller minimum sizes).
Black & white only? Try high-contrast color
QR codes work in any high-contrast color pair. Dark blue on yellow is fine. Red on white is fine. What fails: low contrast (grey on white, dark blue on dark green). When in doubt: black on white.
Static vs dynamic QR codes
Two business models:
Static: the QR encodes the final URL directly. No tracking, no analytics, no destination change.
Dynamic: the QR encodes a short URL. The short URL is resolved server-side to the destination. Trackable, changeable.
For marketing or anything you might want to update, dynamic is the right choice. For business cards or simple sharing, static is fine.
Some commercial tools (qrcode-monkey, qr-code-generator.com) offer dynamic QR services. For self-hosted: any URL shortener works (Yourls, Shlink, custom).
Recommended workflow
- Quick generation: paste URL into QR Code Generator, pick error level M, download SVG.
- For print: SVG output, error level Q, 5cm minimum side.
- For branded code with logo: error level H, logo no more than 25% of area.
- For trackable / changeable codes: encode a short redirect URL. Manage destinations server-side.
- For specialized payloads (Wi-Fi, vCard, TOTP): use the right URI scheme, most QR generators have presets.
The summary: QR codes are simple to generate and easy to mess up. Default to SVG, error level M, plain black-on-white URL, decent size, plenty of quiet zone. Vary from defaults only when you have a specific reason.
Related tools on DevTools Online:
- QR Code Generator, generate QR with error level + format options
- Barcode Generator, for traditional 1D barcodes
- URL Encoder / Decoder, for QR payloads with special characters
- TOTP / 2FA Generator, for QR codes that set up 2FA