What a QR code actually holds
A QR code is a grid of black and white squares, called modules, that encodes bytes. Nothing more. The three large squares in the corners tell a scanner where the code is and which way up it sits; the rest is data, error-correction codewords, and a handful of fields describing how to read them.
WIFI:T:WPA;S:Cafe;P:hunter2;; → a phone offers to join the network, because the prefix is a convention scanners agree on
Because the payload is only bytes, the meaning of a code is a convention between whoever wrote it and whoever reads it — WIFI: offers a network, BEGIN:VCARD offers a contact — which is why picking the right type matters more than it looks. The grid itself comes in 40 sizes, called versions, from 21 modules across up to 177; this tool picks the smallest one your content fits into, so a short link stays a coarse, forgiving code rather than a dense one.
The seven types, and what a phone does with each
Each type writes a different string into the same kind of code. The behaviour column is what a modern iOS or Android camera app offers when it sees one.
| Type | Payload begins | What a scanner offers |
|---|---|---|
| URL | https:// | Opens the address, usually after showing it first. |
| Text | (plain text) | Shows the text. Nothing is opened or dialled. |
| Wi-Fi | WIFI: | Offers to join the network, password included. |
| Contact | BEGIN:VCARD | Offers to save a new contact. |
| SMS | SMSTO: | Opens the messaging app with the number and text filled in. |
| mailto: | Opens a draft with the address, subject and body filled in. | |
| Phone | tel: | Offers to dial the number. |
Whatever the type, the payload is capped at 1,200 characters here. Longer content technically fits in the largest codes, but the result is so dense that phone cameras and consumer printers both start to struggle — at that point a link to the content beats the content itself.
Error correction, and why it is not free
Every QR code carries Reed–Solomon parity alongside its data, so a scanner can rebuild modules that are scratched, smudged, or hidden. The level decides how much of the code can be lost and still decode.
| Level | Recoverable | Reach for it when |
|---|---|---|
| L — Low | 7% | The code lives on a screen, or on print you control and can reprint. |
| M — Medium | 15% | Ordinary printing: posters, packaging, business cards. The default. |
| Q — Quartile | 25% | Industrial or outdoor labels that will collect dirt and scuffs. |
| H — High | 30% | Anything with a logo over it, or a surface that will be handled hard. |
The parity is not magic — it is extra codewords, and they take space. Moving from L to H roughly halves how much content fits in a given version, which pushes the code to a larger version and makes every module smaller at the same printed size. A denser code on cheap paper can scan worse than a sparser one with less parity.
Level M is the default here because it survives ordinary handling without inflating the grid. Reach for H when something is going to sit on top of the code — which is exactly why setting a logo forces H and takes the choice away.
Every option, and when to change it
Styling a QR code is a trade against the one thing it has to do. These are the controls, what each one changes, and the case that justifies it.
| Option | What it does | Reach for it when |
|---|---|---|
| QR code type | Chooses which string is written into the code. | Always — it decides what a phone offers to do. |
| Foreground | Colour of the dark modules. | Matching a brand. Keep it dark. |
| Background | Colour behind the modules. | Sitting the code on a tinted surface. Keep it light. |
| Transparent background | Draws no background at all, so whatever is behind shows through. | Compositing the code onto artwork you already have. Make sure what is behind it stays pale and even. |
| Dot style | Square, individually rounded, or fused into continuous ribbons. | Softening the look. Smooth reads best at larger sizes. |
| Corner eye style | Shape of the three finder patterns. | A distinctive look. Square is the safest with older scanners. |
| Error correction | How much of the code can be lost and still decode. | The code will be printed, handled, or partly covered. |
| Quiet zone | Blank modules around the code. | Fitting the code into a tight layout — reluctantly. |
| Logo | Places an image in the centre on an opaque patch, and forces level H. | The code has to be recognisably yours. |
| Logo size | How much of the code the logo covers. | The logo is unreadable at the default size. Test the result. |
| PNG size | Side of the exported PNG in pixels. | You need a raster of a particular size. Otherwise take the SVG. |
Contrast is the setting people get wrong most often. A scanner has no context to fall back on: it thresholds the image and reads squares. This tool warns below about 7:1, well above the 4.5:1 that body text needs, because a camera in a badly lit room is working with far less than your monitor showed you. Dark on light also beats light on dark — some older scanners will not attempt an inverted code at all.
Logo size ranges from 12% to 28% of the code width. Even at the top of that range and level H, the covered modules plus a scratch can be more than the parity can rebuild, so print one and scan it before committing to a run.
The quiet zone runs from 0 to 8 modules. The specification says four, and that is the default. Dropping it is a design decision to make deliberately: the blank border is how a scanner finds the code’s edge against a busy background.
Dynamic codes: changing a printed code
A static QR code is permanent. The bytes are in the ink, and the only way to change where it goes is to reprint it. A dynamic code solves that by encoding a short link on this site, which redirects to wherever you point it — so the paper stays valid while the destination moves.
Creating one gives you two links. The printed link is short — 8 characters after the domain, drawn from an alphabet with no vowels and no look-alike glyphs, so it survives being read aloud or typed by hand.
The other is the edit link, and it is a credential rather than a URL. It carries a 40-character token, it is shown once, and it is stored here only as a SHA-256 digest — so a copy of the database does not let anyone re-point your codes. The browser that created the code also keeps a copy in its recent-codes list, which is how most people find it again; clear that list, or use another device, and the token is gone for good.
Every scan is counted, along with the time of the most recent one. That is the whole of it: no location, no device, no visitor identifier, and nothing that could distinguish one scanner from another.
There are real trade-offs to weigh before choosing dynamic over static:
- A dynamic code stops working if this site does. A static code works forever and needs nothing from anyone.
- Scanners see a link to this domain, not to yours. Where that matters for trust, print the destination beside the code.
- A short link can point anywhere its owner later chooses, which is why creating one is behind a challenge, why the destination must be http or https, and why a chain of short links pointing at each other is refused.
Reading codes back
The reader decodes with your camera or from a picture you pick. Camera frames are drawn to a canvas in this tab, decoded, and discarded — no frame is uploaded, recorded, or kept, and the scanner stops the moment it finds a code.
What comes back is split into labelled fields, so a Wi-Fi password appears on its own row rather than buried in a WIFI:T:WPA;S:… string. The raw payload is always available underneath, because sometimes that is exactly what you needed to see.
Links found in a scanned code are never opened automatically, and never made clickable unless they are http or https. A QR code hides its destination by design, which is what makes it good for posters and equally good for phishing — read the address before you follow it.
What leaves your browser
Generating never does. The encoder, the Reed–Solomon parity, the styling and the PNG rasteriser all run in this tab. Your Wi-Fi password, your contact details and your links are turned into a code on your own machine, and no request is made while you type.
Reading never does either. Both the camera and the upload path decode locally, and your logo is embedded straight into the SVG as data rather than being uploaded anywhere.
Dynamic codes are the one exception, and they are opt-in. Choosing one sends the destination to this server, which stores it against a short slug so that scans can be redirected and counted. Everything else on this page stays where you typed it.
