7 min read5 sections

Barcodes and QR Codes: A Practical Guide for Developers

Barcodes look simple until they fail to scan. Most scan failures have one of three causes: a wrong check digit, a missing quiet zone, or a payload that exceeds what the chosen symbology can carry. Understanding these rules prevents the most common mistakes before a label goes to print.

1

Check digits: why they matter and how they work

A check digit is a single digit appended to a barcode value that a scanner uses to confirm it read the symbol correctly. EAN-13, EAN-8, UPC-A, and ITF-14 all mandate check digits calculated from the preceding digits using a weighted modulo-10 formula. Code 39 makes its modulo-43 check character optional; Code 128 uses an internal modulo-103 check that the encoder computes automatically.

If you supply an EAN-13 with the wrong check digit, the scanner will reject the read. The error is silent from the user's perspective: the scanner simply does not beep. The most common cause is transcribing a barcode manually and mistyping a digit in the middle, which changes the required check digit. Always let the encoder calculate the check digit from the payload rather than computing it by hand.

2

Quiet zones: the most overlooked requirement

A quiet zone is a blank area of white space on both sides of a barcode that the scanner uses to detect where the symbol starts and ends. Without adequate quiet zones, a scanner cannot distinguish the barcode from whatever is printed next to it.

For linear symbologies such as Code 128 and EAN-13, the quiet zone is typically 10 times the narrowest bar width on the left and right, though the exact minimum varies by standard. For QR codes the specification requires a four-module quiet zone on all four sides. Cropping the quiet zone to save space on a label is the single most common reason a printed barcode will not scan. When designing a label, treat the quiet zone as a structural requirement of the symbol, not decorative white space.

3

Choosing the right linear symbology

Code 128 is the default choice for most internal and logistics applications. It encodes any printable ASCII character, selects automatically between three encoding modes to maximise density, and is supported by every modern scanner. If you have no other constraint, use Code 128.

EAN-13 and UPC-A are retail point-of-sale standards governed by the GS1 specification. You should only use them for products sold through retail channels that require GS1 compliance. The 13-digit EAN and the 12-digit UPC are not freely assignable: the first digits identify the issuing organisation, and allocating numbers requires a GS1 membership or a licensed prefix. Using a made-up EAN-13 for internal barcodes risks collision with a real retail product.

ITF-14 encodes a 14-digit shipping container identifier and is printed directly onto corrugated cardboard. Code 39 is older and less dense than Code 128 but is still found in defence, aerospace, and healthcare systems that standardised on it before Code 128 became widespread. Codabar is used in blood banks and older library systems.

4

QR codes: versions, modes, and error correction

A QR code version is its size, measured in modules. Version 1 is 21×21 modules; each subsequent version adds four modules per side, up to version 40 at 177×177 modules. The encoder selects the smallest version that fits the data at the chosen error correction level. Longer data requires a higher version, which requires a larger physical symbol, which requires a larger print area.

The encoding mode is selected from the data content. Numeric mode fits only digits and encodes three in 10 bits, making it the most efficient for numeric-only payloads. Alphanumeric mode covers uppercase letters, digits, and a handful of symbols. Byte mode encodes any UTF-8 text but is the least dense. The encoder picks the mode automatically, so a purely numeric payload will use numeric mode without any configuration.

Error correction level controls how much of the symbol can be physically damaged or obscured and still decode correctly. Level L recovers about 7% damage; level M about 15%; level Q about 25%; level H about 30%. For a code that will be printed on a product label or scanned outdoors, level M or Q is a sensible default. Level H is appropriate when a logo or design will be placed over part of the symbol, and level L only makes sense when space is extremely tight and the scanning environment is clean.

5

Testing before printing at scale

Before printing a large batch of labels, verify the generated symbol with an independent scanner, not the same software that generated it. A scanner app on a mobile phone is sufficient for a quick check. Verify the decoded value character by character, including any check digit, prefix, or suffix the downstream system expects.

Test the symbol at the smallest size it will be printed, under the lighting conditions it will be scanned in, and at the distances a real scanner will be used at. Reduce the error correction level only as a last resort if the symbol is too large; the right fix is usually more space on the label.

  1. Generate the barcode at the intended data payload and symbology.
  2. Download the SVG and print a test label at the production print size.
  3. Scan with an independent app and verify the decoded value matches exactly.
  4. Check the quiet zones are present on all sides in the printed output.
  5. If scanning fails, check the quiet zone and then increase the module size before changing the symbology.