Methodology
On this page
- QR data encoding
- Error correction
- Quiet zone
- QR verification
- Barcode check digits
- Barcode rendering
- 2-D symbologies and how they are verified
- Scan-reliability rating
- ISBN, ISSN and GS1 data
- Formats we deliberately do not offer
- Bulk generation and archives
- Browser compatibility and limits
- What this site actually runs
- Check it yourself
- Public test vectors
- What we tested, and when
- Known limitations
This page explains how our tools work under the hood, so you can trust — and verify — what they produce.
QR data encoding
Text is encoded as UTF-8 and passed to a well-tested QR generation library, so emoji and non-Latin scripts are preserved. Structured types (Wi-Fi, vCard, email, SMS, tel, geo, iCalendar, WhatsApp) are assembled using their standard formats, with special characters escaped as each specification requires.
Error correction
You choose the error-correction level (L, M, Q or H). Adding a logo automatically raises the level to H to compensate for the covered modules. See our error-correction guide.
Quiet zone
We include a configurable quiet-zone margin (four modules by default) because scanners rely on that empty border to locate the code.
QR verification
The Verify feature re-decodes the generated image in your browser and compares the result against the exact data you entered. It reports whether the code was generated, decoded, and whether the content matches — flagging issues such as low contrast or an oversized logo.
Barcode check digits
UPC-A, EAN-13, EAN-8 and ITF-14 use a modulo-10 checksum. We calculate the check digit from your input, or validate the one you provide, and show the full calculation. This logic lives in a standalone module with automated tests covering both valid and invalid numbers.
Barcode rendering
Barcodes are drawn with a maintained open-source library that supports the standard 1-D symbologies, output as both SVG (real vector paths) and PNG. Nothing is rasterised and wrapped in an SVG tag — the SVG contains the actual shapes.
2-D symbologies and how they are verified
Data Matrix, GS1 DataMatrix, PDF417 and Aztec Code are encoded with a build-time extract of bwip-js, which is generated from Barcode Writer in Pure PostScript — the reference implementation these symbologies are usually checked against. Only the four encoders are bundled, in raw mode: they return a module matrix and this site draws it, so colour, quiet zone, SVG output and downloads work exactly as they do everywhere else.
These formats ship on one condition, recorded in our engineering decisions: every symbol the site can produce is decoded back by a different library before release. The test encodes each case, rasterises it exactly as the browser draws it, decodes it with ZXing, and compares the result against the original input character for character. A shared bug cannot make both sides agree, because the encoder and the decoder come from unrelated codebases. It covers every symbology, every option the pages expose, and non-ASCII input.
PDF417 rows are rendered at the 3:1 row-height ratio ISO/IEC 15438 specifies, and that ratio is not adjustable — a symbol squashed to fit a layout is a symbol that stops scanning. Data Matrix always uses ECC 200, because the standard fixes it. Aztec needs no quiet zone by specification; two modules are added anyway because it costs nothing and helps handheld readers.
Scan-reliability rating
The Good / Needs attention / High risk rating beside the QR preview is a set of heuristics over the design: contrast ratio, quiet-zone width, data density, logo coverage against the error-correction level, export resolution and content length. It is not a certified print grade — a real grade (ISO/IEC 15415) measures a printed symbol with calibrated optics. What we can check from a browser is the design, which is where the large majority of real-world failures start.
ISBN, ISSN and GS1 data
ISBN-10 uses the modulo-11 checksum from ISO 2108 and ISBN-13 the GS1 modulo-10 checksum; conversion between them recalculates the check character, and 979-prefixed numbers are correctly reported as having no ISBN-10 form. ISSN uses the ISO 3297 modulo-11 checksum before being placed into a 977-prefixed EAN-13. GS1-128 Application Identifiers are validated for data type, length, date format and check digit, and FNC1 separators are inserted according to the predefined-length rules in the GS1 General Specifications.
Formats we deliberately do not offer
Code 93 is not available here, and neither are price and issue add-on symbols for ISBN and ISSN: the vendored 1-D renderer cannot produce them, and a hand-written implementation would risk labels that look right and fail in a supply chain. Within the 2-D formats we do offer, Macro PDF417, Aztec Runes, structured append and the ECI protocol for declaring alternative character sets are all out of scope. We would rather support fewer formats completely than more of them approximately.
Bulk generation and archives
Bulk jobs validate every row with the same rules as the single-code tools, then render in chunks that yield to the browser between batches so the page stays responsive and cancellable. The ZIP archive is assembled by a small archive writer built into the page, using the platform's own deflate where it is available.
Browser compatibility and limits
Camera scanning and native barcode detection depend on browser support, which varies by device. Where a native barcode detector isn't available, only QR codes can be scanned. Torch and zoom controls appear only when the camera actually reports those capabilities. Image upload works as a universal fallback.
What this site actually runs
Everything below is vendored into /assets/vendor/ and served from this domain. There are no CDN requests at runtime, which is what makes the privacy promise on this site checkable rather than a claim.
| Library | Version | Licence | What it does here |
|---|---|---|---|
| qrcode-generator | 1.4.4 | MIT | QR encoding. Patched at load so text is encoded as UTF-8 rather than the library default of Latin-1. |
| JsBarcode | 3.11.6 | MIT | 1-D barcode drawing, to SVG and canvas. |
| jsQR | 1.4.0 | Apache-2.0 | QR decoding, for “Verify scan” and as the scanner fallback where the browser has no Barcode Detection API. |
| bwip-js / BWIPP | 4.11.2 (build-time extract) | MIT | Data Matrix, GS1 DataMatrix, PDF417 and Aztec encoding, in raw matrix mode. |
| zxing-wasm (ZXing) | 2.2.4 | MIT | Build-time only. Decodes every symbol the site can produce, so the round-trip tests are checked by a codebase unrelated to the encoders. Never shipped to a visitor. |
CSV parsing, ZIP writing and PDF output are implemented in this repository rather than pulled in as dependencies. Camera scanning uses the browser's own Barcode Detection API where it exists.
Check it yourself
You do not have to take any of this on trust. Three checks, in rising order of effort:
- Read the encoded value. Every QR page has an Encoded data box showing the exact string that went into the symbol — the escaped
WIFI:orBEGIN:VCARDpayload, not a summary of it. Compare it against the specification. - Decode it with something else. Download the PNG and open it in a decoder that has nothing to do with this site — your phone's camera app, or any independent online decoder. The string it reports must match the Encoded data box character for character.
- Watch the network. Open your browser's developer tools, switch to the Network tab, and generate a code. Nothing you typed appears in any request. This is asserted automatically on every build as well: a known marker string is typed into a generator and every outgoing request is checked for it.
For barcodes, the same applies with the check digit: the page shows the full modulo-10 or modulo-11 working, so you can reproduce it by hand.
Public test vectors
These are the numbers our automated tests use. They are published so you can confirm the calculators agree with a reference before trusting them with your own data.
| Symbology | Payload | Check digit | Full value |
|---|---|---|---|
| UPC-A | 03600029145 | 2 | 036000291452 |
| EAN-13 | 400638133393 | 1 | 4006381333931 |
| EAN-8 | 9638507 | 4 | 96385074 |
| ITF-14 | 0001234567890 | 5 | 00012345678905 |
| ISBN-10 | 030640615 | 2 | 0-306-40615-2 |
| ISBN-13 (from the ISBN-10 above) | 978030640615 | 7 | 9780306406157 |
| ISSN | 0317847 | 1 | 0317-8471 |
| GS1 element string | (01)09521234543213(17)261231 — GTIN check digit 3, expiry 31 Dec 2026, no separator after the fixed-length AI 17 | ||
A number with a deliberately wrong check digit — 036000291453, 4006381333930, 00012345678904 — must be rejected with the corrected value offered, not silently drawn.
What we tested, and when
Automated: 166 unit tests, 30 SEO and structure tests, 35 QR round-trip cases, 25 two-dimensional round-trip cases, 222 layout and accessibility checks and 45 end-to-end quality checks. Every push runs them; a failure blocks the build.
| Engine | Version at last run | What was run |
|---|---|---|
| Chromium (Blink) | 151.0.7922 | Full suite: layout at twelve widths in both themes, axe-core WCAG 2.1 A/AA, generator behaviour, 1-D round trip, downloads, bulk CSV, privacy assertions |
| WebKit (Safari engine) | 26.5 | Same suite, excluding the axe pass |
| Gecko (Firefox) | — | Not run in the last cycle: the test machine could not launch the bundled Firefox build. Firefox-specific behaviour on this site is limited to QR-only scanning, which is the same path WebKit exercises. |
Last full test run: 29 August 2026 (UTC). Camera scanning on physical phones and printing to real label stock are checked by hand, not by the automated suite — a headless browser has no camera and no printer. What changed and when is recorded in the changelog.
Known limitations
- The scan-reliability rating grades a design, not a printed symbol. It cannot tell you what an ISO/IEC 15415 verifier with calibrated optics would say about the label in your hand.
- Bulk runs are limited by browser memory — around 500 codes per batch in practice.
- Camera scanning needs HTTPS and a browser that grants camera access; in-app browsers on iOS frequently do not.
- Which symbologies the live camera can read depends on the browser's own detector, so the list differs between devices. The page reports what it actually found rather than a fixed list.
- Generating a UPC or EAN image does not register a number. GTINs are issued by GS1 — see the disclaimer.