What a QR code actually stores
A QR code is a grid of black and white squares called modules. Version 1 is 21×21 modules and every version adds four to each side, up to version 40 at 177×177. The three big squares in the corners are finder patterns that tell a scanner where the code is and which way up it sits; the rest carries your data plus its error-correction blocks. The tool shows the version and module count under the preview as you type, so you can watch the code grow.
How much fits depends on what you encode. Digits pack tightest, uppercase letters with a few symbols come next, and everything else (lowercase, Korean, emoji) is stored as raw bytes. At the lowest error-correction level a full version 40 code holds about 7,089 digits, 4,296 alphanumeric characters or 2,953 bytes — which is roughly 980 Korean characters in UTF-8.
Shorter payloads are not just smaller files — they are easier to scan. A 30-character link at level M produces a version 3 code (29×29) whose modules are large and forgiving; the same link with 200 characters of tracking parameters lands around version 9 (53×53), with modules a third the size that a phone must resolve from further away.
The seven types, and the exact text each one encodes
- Link — the URL as typed, with https:// added when you type a bare host. An existing scheme (http:, mailto:, tel:, myapp:) is never touched.
- Wi-Fi — WIFI:T:WPA;S:MyNetwork;P:secret;H:false;; Semicolons, commas, colons, quotes and backslashes inside an SSID or password are escaped, so a network called “Café; 2F” still works. Open networks use T:nopass and omit the password.
- Contact — a vCard 3.0 block with N (structured name), FN (display name), and ORG, TITLE, TEL;TYPE=CELL, EMAIL and URL when filled. Commas, semicolons and line breaks are escaped per RFC 6350, so a surname like “Smith, Jr” imports as one name instead of two.
- Email — mailto:you@example.com?subject=…&body=…, with the subject and body percent-encoded so line breaks and non-Latin text survive.
- SMS — SMSTO:+821012345678:message, and Phone — tel:+821012345678. Spaces, hyphens and brackets are stripped from numbers while a leading + is kept, because +82-10-1234-5678 and (010) 1234-5678 must both dial correctly.
- Text — encoded verbatim. Use it for a serial number, a note, a Wi-Fi guest instruction or anything that is not a link; scanners will show it as plain text rather than opening an app.
Error correction L, M, Q, H — what you are trading
Reed–Solomon error correction lets a scanner rebuild the payload from a damaged code. The four levels recover roughly 7 % (L), 15 % (M), 25 % (Q) and 30 % (H) of the codewords. That redundancy is data too, so a higher level means more modules for the same content — and modules that are physically smaller if the printed size does not change.
Use M — the default — for anything on a screen, where nothing is going to get scratched. Use Q or H for printed material: posters that get rained on, table tents that get spilled on, stickers on packaging that curve and scuff, and any code with a logo covering the middle. L is worth it only when the payload is long and the code will live on a clean screen.
Watch the version readout while you switch levels: the same 120-character URL might be version 6 at L and version 8 at H. If the code jumps a few versions and it has to be printed small, shorten the URL rather than dropping the error-correction level — a short URL at H scans better than a long one at L.
Size, quiet zone and printing big enough to scan
The on-screen size slider runs from 128 to 1,024 px, and the PNG export adds a 1×, 2× or 4× multiplier on top, capped at 4,096 px. The export renders by whole module pixels rather than scaling to a target width, so module edges stay crisp instead of being resampled into grey fringes that confuse a scanner.
The quiet zone is the blank border, measured in modules. The QR specification requires 4, which is the default here; you can go to 0 for a design mock-up or up to 16, but a code printed edge-to-edge against artwork frequently fails to scan. Do not fill the quiet zone with a background pattern.
For print, the working rule is scan distance ÷ 10: a code read from 2 m needs to be about 20 cm wide, one read from 30 cm needs about 3 cm. Never print smaller than 2 cm — that is roughly the practical floor for a business card — and give a 300 dpi print job at least a 1,000 px PNG, or use the SVG.
Colours and contrast
Scanners look for dark modules on a light background. The tool computes the WCAG relative luminance of both colours and warns in two cases: when the foreground is lighter than the background (an inverted code, which many phone cameras refuse outright), and when the contrast ratio falls below 3:1. Both are warnings, never blocks — you may know your audience’s scanner handles it.
Brand colours usually work if they are dark: a deep navy or forest green on white scans as well as black. Pastels, mid greys and yellow on white do not. Aim for at least 4:1 against the background and test with the oldest phone you can find, not the newest.
If you are placing the code on a photograph or a gradient, put it on a solid panel instead. Contrast that varies across the code is the single most common reason a printed QR fails while the same file scanned fine on screen.
PNG or SVG — which download to take
PNG is a bitmap at a fixed pixel size. Take it for websites, slide decks, social posts, email signatures and anything that will be viewed at roughly the size you exported. Use the 2× or 4× buttons when you need a larger file; 1,024 px at 4× reaches the 4,096 px cap.
SVG is vector: the same file is sharp on a business card and on a shop window. Take it for anything going to a printer, a laser cutter, a vinyl plotter or a designer — it opens in Illustrator, Inkscape, Figma and every browser, and it can be recoloured without re-generating the code.
“Copy PNG” puts the image straight on the clipboard for pasting into a document or a chat; the button only appears in browsers that support writing images to the clipboard. Downloads are unlimited, unwatermarked and require no account, because the code is generated on your device and there is nothing to gate.
Codes that will not scan — and how to fix them
- Too much data. Past the version 40 ceiling the generator reports that the content is too long. Shorten the text, or put a link in the code and the long content behind it.
- Printed too small or too close to the edge. Apply the distance ÷ 10 rule and keep the 4-module quiet zone clear of other artwork.
- Wrong Wi-Fi details. Passwords are case-sensitive, the security type must match what the router actually uses (WPA covers WPA2 and WPA3-personal; WEP is legacy), and a hidden network needs the Hidden switch on or the phone will not find it after decoding.
- Enterprise Wi-Fi. The WIFI: format has no place for a username and certificate, so a WPA2-Enterprise network cannot be joined from a QR code at all — that is a limitation of the format, not of this tool.
- A logo covering the middle. Keep it under about 20 % of the code’s area, never let it touch the three corner finder patterns, and generate at level H so the covered modules can be reconstructed.
Always scan the finished code with two different phones before printing a thousand of them. Thirty seconds of testing costs less than a reprint.
Static codes: no tracking, no expiry, no upload
These are static QR codes: the content lives inside the pattern itself, not behind a redirect owned by someone else. That means they never expire, never stop working because a service shut down or a subscription lapsed, and generate no scan analytics — and it also means the destination cannot be changed after printing. If you expect to change it, encode a short link you control and repoint that.
Generation happens entirely in this tab. Only Link and Text payloads shorter than 300 characters are mirrored into the page URL so a code can be shared as a link; Wi-Fi passwords, vCard details, email bodies and SMS text are deliberately kept out, so copying the address bar cannot leak them into browser history, a referrer header or a chat message.
Design settings — error correction, size, margin and the two colours — are remembered in this browser so the next code matches the last one. They are stored locally and describe styling only; no payload is ever saved.