The short answer
Shorten the payload, print matte, keep the code off the curve, and make it dynamic.
The generic advice you will find elsewhere, a minimum of about 2 x 2 cm, is a reasonable floor but an incomplete rule. It describes the printed size and says nothing about how much data you are asking that square to hold, which is the variable most likely to be wrong on a pack.
For the general relationship between scan distance and printed size, our size guide covers the arithmetic. This article is about the things that are specific to packaging: substrate, finish, curvature, press behaviour, and batch-level data.
Why the standard minimum size advice is incomplete
A QR code is a grid of modules, and what a phone camera has to resolve is one module, not the whole code. Printed size sets the outer dimension. Payload length sets how many modules have to fit inside it. Both matter, and only one of them shows up in most guidance.
We encoded four payloads a packaging team would realistically use, all at error correction M, and calculated the module size at three common pack dimensions. Quiet zone is included in the divisor, because the four-module margin is part of what has to fit.
| Payload on the pack | Modules | 1.0 in (25.4 mm) | 1.5 in (38.1 mm) | 2.0 cm (20 mm) |
|---|---|---|---|---|
| Short dynamic link | 25 | 0.77 mm | 1.15 mm | 0.61 mm |
| Product page URL | 29 | 0.69 mm | 1.03 mm | 0.54 mm |
| URL with batch and lot code | 33 | 0.62 mm | 0.93 mm | 0.49 mm |
| Long URL with UTM tags | 37 | 0.56 mm | 0.85 mm | 0.44 mm |
Tips
- At 2 x 2 cm, moving from a UTM-tagged URL to a short dynamic link takes the module from 0.44 mm to 0.61 mm, a 39% increase, with no change to the printed size.
- Going up an error correction level moves in the opposite direction. See [error correction levels](/blog/qr-code-error-correction-levels) for the measured cost of each level.
- If a pack has room for only a small code, the answer is a shorter destination rather than a smaller module.
Substrate and finish
The material under the ink decides how clean the module edges are, and clean edges are what a camera needs.
Coated stock holds a sharper edge than uncoated. Uncoated board and kraft absorb ink and spread it, which thickens dark modules and narrows the light gaps between them. On kraft in particular, budget for a slightly larger code than you would use on a coated carton.
Finish matters more than most teams expect. A high-gloss varnish or laminate reflects the phone's own screen and any overhead light straight back into the lens, and a specular highlight across the pattern reads as missing data. Matte and silk finishes diffuse that reflection. If the pack has to be glossy for brand reasons, ask the printer for a matte spot varnish over the code area only, which is a routine request and usually free at plate stage.
Metallic and foil substrates are the hardest case, because the base surface is a mirror. Print the code in a solid dark ink over a solid light patch rather than letting the foil serve as the light modules. Clear film and shrink-wrap introduce a second problem, distortion, since the film moves during application and the pattern moves with it.
Tips
- Dark modules on a light background, always. Inverted codes scan on some phones and fail on others.
- Contrast between the two colours matters more than which colours they are. Two mid-tone brand colours will fail where black on white succeeds at the same size.
- Ask for a matte spot varnish over the code area if the rest of the pack is gloss.
Curved surfaces
Bottles, cans, tubes, and jars bend the pattern away from the camera, and the parts of the code nearest the edge of the curve foreshorten until the modules merge.
Two rules cover most of it. Keep the code off the apex of the curve, positioned so it sits on the flattest available panel, and orient it so the curvature runs vertically through the pattern rather than horizontally, because most people hold a phone in portrait and the camera tolerates vertical distortion better than horizontal.
The tighter the radius, the larger the code needs to be. A 2 litre bottle is nearly flat across a 2 cm code. A lip balm tube is not, and on containers that narrow you are usually better served by a code on the end cap or the outer carton.
Raising the error correction level helps a little here, because foreshortening damages a contiguous region rather than scattering errors. It is not a substitute for placement, and it costs modules, so treat it as the second adjustment rather than the first.
What the press does to your code
Dot gain is the press spreading ink beyond the intended edge, and it affects QR codes more than it affects type because the pattern depends on the light gaps staying open.
Flexographic printing, which is standard for flexible packaging and much label work, gains more than offset litho. Digital presses gain least. If the code will run flexo on film, tell the printer it is a machine-readable element so they can compensate at plate stage rather than treating it as artwork.
Supply the code as vector. A vector export gives the prepress team clean paths they can trap and compensate; a raster PNG placed at 2 cm and scaled up gives them soft edges and no options. This is the single most common avoidable defect we see described in packaging workflows.
Colour build matters too. A code built from a four-colour black registers slightly differently on each unit than one built from a single solid black, and misregistration blurs module edges. Ask for 100% K rather than a rich black.
Tips
- Always supply vector (SVG, PDF, or EPS) for packaging, never a placed PNG.
- Specify 100% K rather than a rich black build, to avoid registration blur on module edges.
- Tell the printer the code is machine-readable so it is not treated as decorative artwork.
Where the code goes on the pack
Back panel remains the default, and for good reason: it is usually the flattest area, it is not competing with the primary brand mark, and shoppers already turn packs over to read ingredients.
What separates a code that gets scanned from one that does not is the line of text beside it. A bare code is a question mark. A specific promise is an invitation, and the difference is measurable in scan rate. Our call-to-action design guide goes further on the wording, and the short version is that the label should say what the person gets rather than what the technology is.
Leave the quiet zone clear. The four-module margin around the pattern is part of the code, and packaging is exactly where it gets encroached, because layouts are tight and a designer nudges a nutrition panel one millimetre closer at the last revision.
One placement to avoid: across a seam, fold, or the glue flap. The code will be creased in production and scanned across a discontinuity in the field.
Per-batch codes, traceability, and recalls
This is where packaging QR codes stop being marketing and start being operations, and it is the strongest argument for generating them in bulk rather than one at a time.
A per-batch code carries lot-level data: production date, facility, ingredient lots, certificates. Generate one code per batch with bulk CSV import rather than by hand, and the print run for each batch carries its own identifier.
The regulatory picture is worth stating precisely, because it is widely misreported. In the US, FDA FSMA 204 requires traceability records for foods on the Food Traceability List, with a compliance date of 20 July 2028. The rule requires records, not a QR code, though a code is the most practical way to attach those records to a physical case. In the EU, wine has carried an ingredients and nutrition requirement since 8 December 2023 under Regulation 2021/2117, and producers may present the full detail on an electronic label reached by a QR code. The EU Digital Product Passport, by contrast, explicitly excludes food and feed, so it is not the driver for grocery packaging that some coverage suggests.
Recalls are where dynamic codes earn their place. When a supplier flags a contaminated ingredient lot, you repoint the affected batches' codes to a recall notice, and units already on shelves start showing it on the next scan. A static code cannot do this, because its destination is welded into the pattern.
For category-specific detail, see food manufacturing, wine and spirits, and retail.
Static or dynamic on a pack
Dynamic, in almost every packaging case, and the reasoning is economic rather than technical.
A packaging reprint is expensive and slow. Plates, press time, and obsolete stock all cost real money, and the destination behind a pack code changes more often than teams expect: a campaign ends, a product page moves, a recipe hub gets restructured, a recall happens. A dynamic code keeps the printed artwork valid through all of that.
Dynamic codes are also shorter, which is the point made in the measurement section above. A short redirect encodes fewer characters than a UTM-tagged campaign URL, which means fewer modules, which means larger modules at the same printed size. On packaging the dynamic code is both more flexible and more scannable, which is not a trade-off you often get.
Static still has its place. If the code points at a homepage that will not move, and the pack is a one-off, a static code has nothing to maintain and no dependency on anything. Just be honest about whether the destination is genuinely permanent.
Pre-press checklist
Run this before the artwork goes to the printer, not after the proof comes back.
Tips
- Payload is as short as it can be, ideally a short dynamic link rather than a tagged campaign URL.
- Code supplied as vector, with 100% K specified rather than a rich black.
- Quiet zone of four modules clear on all sides, verified on the final layout rather than the artwork file.
- Finish is matte or silk over the code area, even if the rest of the pack is gloss.
- Placement avoids seams, folds, glue flaps, and the apex of any curve.
- A specific call to action sits beside the code, saying what the scan gives the person.
- Printed proof scanned on at least three phones, including an older Android, at the distance a shopper will actually use.
- For batch-level codes, the mapping from lot number to destination is recorded somewhere other than the printer's file.