toys

qr code.

Paste a URL or any text, pick a size and error-correction level, then download or copy the image. Below the tool, the bits explained.

generate a qr code

0 / 2000
error correction (higher = more damage tolerated)
type something to generate

how qr codes actually work

A QR code is a 2D bitmap. Black and white squares, called modules, are arranged on a grid that ranges from 21×21 (Version 1) to 177×177 (Version 40). The grid encodes a sequence of bits, and a phone camera reads them back by detecting contrast.

QR anatomy
finder patternstiming patternsdata + error correction

The grid is split into regions with different jobs:

  • Finder patterns — three big squares in the corners. They tell the scanner where the code is and how it's rotated. Their 1:1:3:1:1 ratio of dark and light rows is unique enough that finding them is fast.
  • Timing patterns — the dotted line connecting the finders. It tells the scanner the size of one module so the rest of the grid can be sampled accurately.
  • Format and version info — strips next to the finders, encoding which error-correction level was used and which masking pattern was applied.
  • Data and error-correction modules — everything else. Your URL ends up here, interleaved with redundancy bits.

why error correction matters

QR codes use Reed–Solomon error correction. The encoder takes your data, breaks it into blocks, and computes redundancy bytes for each block. If part of the code gets scratched, smudged, or covered by a logo, the scanner uses the redundancy to reconstruct what the missing modules said.

The four levels you can pick above trade capacity for resilience:

  • Low — recovers ~7% of damage. Densest QR for a given length.
  • Medium — ~15%. Sensible default.
  • Quartile — ~25%.
  • High — ~30%. Great if you'll print it on a sticker that might peel, or overlay a logo in the centre. The QR gets denser to fit the same data.

If you see "too long for this error-correction level", that's the encoder telling you the requested redundancy doesn't fit alongside your text in the largest version (40). Drop a level or shorten the text.

a final touch: masking

Before the bits are placed, the encoder XORs them with one of eight predefined patterns — diagonals, checkerboards, stripes. The mask that produces the most balanced spread of black and white modules wins. Without masking, encoding "aaaaaa" would produce big solid blocks that scanners hate.

how this tool is built

It's a small client-side React component. The qrcode npm package does the encoding, masking, and module placement, and paints directly into a <canvas>. The size buttons set the canvas pixel width; the error-correction buttons map straight onto the L/M/Q/H levels in the spec.

Download uses canvas.toBlob + an <a download> trick — no server round trip. Copy uses navigator.clipboard.write with a ClipboardItem, which is the only way to put a real PNG (not a data URL) on the system clipboard so apps like Slack and Notes paste it as an image.

The QR re-renders when you toggle dark mode — the colours track your theme. The PNG you download or copy uses whatever palette is on screen. Switch to light mode first if you plan to print on dark paper.

← back to toys