The decision that outlives the print run
A static QR code carries the URL inside the pattern. Whatever you encode is what every scanner gets, for as long as the box exists. That is fine until the campaign ends, the landing page moves, the product gets a new manual, or the app launches on a second platform. Then the code points at something that no longer exists, and the only fixes are a reprint or a redirect maintained at your own domain forever.
A dynamic code encodes a short link you control. The pattern never changes; the destination is a setting. Packaging is where this matters most, because packaging is the one surface you cannot update: a poster comes down, a website is edited, a print run of 50,000 cartons sits in a warehouse for two years doing exactly what it was told.
The practical version of this: you can send artwork to the printer before the destination exists. Ship the code on the box, point it at a holding page, and switch it to the real page, or the app store listing, on launch day.
Size, and the rule of thumb worth testing
The usual guidance is that a code should be roughly a tenth of the distance it will be scanned from. Arm's length, call it 20cm, gives about 2cm across. A shelf-edge code read from a metre away wants 10cm, which is more panel than most packs will give up.
Treat that as a starting point, not a spec. What actually decides it is how much data you encode and how well your process prints fine detail. A long URL needs more modules at the same physical size, so each module gets smaller and the print has to hold it. This is a quiet argument for a short redirect link over a long tracked URL with parameters bolted on: fewer characters means a coarser, more forgiving pattern.
Print a proof at final size, on the real substrate, and scan it with a cheap phone in bad light. That test costs an afternoon and catches things no calculator will.
Error correction, placement, contrast
Error correction adds redundant modules so a damaged code still reads. For packaging, M or Q is the usual balance. Go to H when a logo sits over the centre or the surface will visibly wear, and accept that the pattern gets denser at the same size.
Placement wants somewhere flat: not across a fold, not on the seam, not around the curve of a bottle, not where a hand grips. Leave the quiet zone, about four modules of clear space on every side. Packaging design crowds it constantly, and a code with a border touching it fails intermittently, which is worse than failing outright because nobody reports it.
Contrast and finish decide the rest. Scanners want dark modules on a light background; inverted codes are not read reliably by every app. Gloss and metallic finishes throw glare under shop lighting. A matte light patch behind a dark code is dull and it works.
One code, more than one destination
If the pack promotes an app, the code does not have to choose a platform. Device routing sends an iPhone to the App Store, an Android phone to Google Play, and a desktop to your website, from one printed pattern. Two codes side by side spend panel space making the customer solve a problem you could have solved for them.
The same mechanism splits by country, which on packaging usually means sending each market to its own language page or regional store. Rules are read top to bottom and the first match wins, so the specific ones go above the general ones.
What the scan data will and will not tell you
A dynamic code counts each scan with the device and approximate location. For packaging that is often the only signal that exists between the shelf and you, and it answers real questions: is the code being found at all, which market is scanning, did the redesign change anything.
It counts scans, not people, and it cannot connect a scan to a purchase. Someone scanning in a shop and not buying looks identical to someone scanning at home after buying. Treat it as a measure of attention, not of conversion.