I work on OnePassApps, and we build the browser apps behind this post. This one is the QR Code Maker: it renders a static QR code in your tab and hands back a PNG or an SVG you can print. Every code maker gives you an error-correction level, and almost none of them tell you what that choice does to the file. So I ran all four levels against the same 48-byte address, read the panel at each one, and then read the exported files off disk outside the browser.

Try it on the QR Code Maker, or read the guide.

What each level does to the grid

The panel states its scope up front: "Make a static QR code for a link, text, Wi-Fi, contact, email, phone or SMS, then download it as PNG or SVG." The field hint is "Starts with http or https. https:// is added if you leave it out." and the recovery figure is printed per level: "Level L can recover about 7% of a damaged code. Higher levels make a denser code."

With one address in the field and everything else left alone, the DETAILS block read:

  • L - "Version 3 of 40 (29 × 29)", "Error correction L, recovers about 7%", "Mask 3", "Data mode byte", "Capacity used 48 bytes · 90% of 55 data bytes", "PNG size 370 × 370 px"
  • M - "Version 4 of 40 (33 × 33)", "Error correction M, recovers about 15%", "Mask 2", "Data mode byte", "Capacity used 48 bytes · 77% of 64 data bytes", "PNG size 410 × 410 px"
  • Q - "Version 5 of 40 (37 × 37)", "Error correction Q, recovers about 25%", "Mask 7", "Data mode byte", "Capacity used 48 bytes · 80% of 62 data bytes", "PNG size 450 × 450 px"
  • H - "Version 6 of 40 (41 × 41)", "Error correction H, recovers about 30%", "Mask 7", "Data mode byte", "Capacity used 48 bytes · 83% of 60 data bytes", "PNG size 490 × 490 px"

What each level does to the file

Every export was read back off disk, outside the browser, so these are the real file sizes:

  • PNG: 5,353 bytes at L, 6,352 at M, 7,522 at Q, 8,831 at H
  • SVG: 3,224 bytes at L, 4,208 at M, 5,107 at Q, 6,386 at H
  • Pixel width and height: 370, 410, 450, 490 px

The PNG at every level is 8-bit RGBA with an IHDR chunk, its IDAT data and an IEND, and no text chunk of any kind, so nothing is hidden in it.

The geometry, checked in code

The module grid is what sets the pixel size. I rebuilt the arithmetic in a script rather than trusting the panel: the code is 29 × 29 at L and 41 × 41 at H, so it is 841 modules against 1,681 - just under double the modules in the same square of paper. Adding the quiet zone and scaling by the module scale gives (modules + 2 × 4) × 10 px = 370, 410, 450 and 490 px, which matches the PNG IHDR at all four levels exactly.

The part that surprises people: capacity shrinks

Read the budget figures again for the same 48 bytes of content: 55 data bytes at L, then 64 at M, 62 at Q and 60 at H.

The budget does not climb with the level. A higher level forces a higher version, and the extra redundancy in that version eats data codewords, so what is left for your content shrinks. At L the address fills "90% of 55 data bytes"; at H it fills "83% of 60 data bytes".

That matters for long content. The guide sets the outer limit: "Capacity is up to 2,953 bytes at level L, and a PNG can be up to 4,096 pixels a side." A long Wi-Fi payload or a vCard pushes you up a version, and every version up costs density at the same printed size.

The SVG is the one to print

The SVG carries the image role, the same pixel width and height as its PNG, and a viewBox of "0 0 37 37" at level L - 37 module-widths across for a 29-module code, the extra eight being the quiet zone around it. There is no script tag and no external reference in it.

What the app will not do

The guide is plain about the edges: "Codes are static only: no logos, shaped modules, dynamic links or tracking."

The panel adds the operational half: "Static code: the content is in the image itself, so it keeps working without us." and "Nothing leaves this tab." A downloaded PNG keeps working with no server behind it - but the other half of that is that a code you have not downloaded is gone: "Reloading discards the code, so your download is the record."

And the panel ends with the advice that matters most for a printed code: "Always test a printed or on-screen code with the phones and apps your audience uses."

Cost

The plan block reads "Standard is free right now", "$0 / month" and "100,000 credits every 30 days · No end date set · No card required", with "No automatic paid subscription. Existing paid subscriptions keep their terms." The line that matters for this tool is on the guide: it "never uses OnePassApps credits".

What I did not test

One build, one browser, one signed-out session, 6 November 2026.

  • One address, the same one at all four levels. The Type control is a combobox and I did not open it, so the Wi-Fi, contact, email, phone and SMS types were not exercised.
  • Module scale and quiet zone were left at their defaults and their input values were not read, so 10 px per module and the four-module quiet zone are derived from the exported PNG width and the SVG viewBox, and they agree at every level.
  • Foreground and background stayed at the app's defaults, and the panel's readout held at "Contrast is 18.9:1, which suits scanners." across all four levels.
  • No phone scanned any of the four codes and nothing was printed, so I am not claiming how any of them scanned.

If you are choosing a level: H for a poster that will get scuffed or rained on, L or M for a sticker a phone has to read up close, and always test the printed one. The tool will tell you the size and the density before you commit.

I work on OnePassApps, so this is our own build, measured on 6 November 2026. If your copy of the panel says something different, trust your screen - the app changes faster than posts do.