Project Nayuki

Creating a QR Code step by step

This JavaScript demo application visualizes in detailed steps, how a text string is encoded into a QR Code barcode symbol. The content of this page essentially explains and justifies how my QR Code generator library works internally.

User input

Show example:
Text string:
Error correction level:
Force minimum version: (between 1 and 40)
Force mask pattern: (−1 for automatic, 0 to 7 for manual)

QR Code output

Step-by-step process

Show/hide each step:

0. Analyze Unicode characters

Number of code points in the input text string:

Details of each character:

Index Char CP hex NM AM BM KM

Can every character be encoded in:

Mode Encodable

Chosen segment mode to encode all characters:

1. Create data segment

Convert each character to bits. For numeric and alphanumeric modes, consecutive characters are grouped together before being encoded into bits. For byte mode, a character produces either 8, 16, 24, or 32 bits.

Index Char Values (hex) Value Combined Bits

The created single segment:

  • Mode:
  • Count:
  • Data:

(This demo program always creates a single segment for simplicity. But it is possible to segment the text optimally to minimize the total bit length.)

2. Fit to version number

Size of the list of segments, depending on version:

Range Num bits Num codewords
Version 1 ~ 9
Version 10 ~ 26
Version 27 ~ 40

(Note: A codeword is defined as 8 bits, also known as a byte.)

QR Code capacity of data codewords per version and error correction level, and whether the data fits:


Chosen version number:

3. Concatenate segments, add padding, make codewords

Join a variety of bit strings together:

Item Bit data Num bits Sum bits


  • The terminator is normally four “0” bits, but less if the data codeword capacity is reached.

  • The bit padding is anywhere from zero to seven “0” bits, to fill all unused bits in the last byte.

  • The byte padding consists of alternating EC and 11 until the capacity is reached.

The entire sequence of data bits:

The entire sequence of data codeword bytes (by splitting the bit stream 8 bits at a time) (displayed in hexadecimal):

4. Split blocks, add ECC, interleave

Statistics about all blocks:

Number of data codewords:
Number of blocks:
Data codewords per short block:
Data codewords per long block:
ECC codewords per any block:
Number of short blocks:
Number of long blocks:

Split the sequence of data codewords (green) into short and long blocks; then for each block, compute the ECC codewords (blue) and append them to the end of the block:

Block index

(Note: The math behind computing the Reed-Solomon error correction codes is omitted because it is long, tedious, and not very interesting.)

The final sequence of codewords formed by interleaving data/ECC codewords from different blocks:

The final sequence of bits to draw in the zig-zag scan:

5. Draw fixed patterns

Draw the horizontal and vertical timing patterns (on both row 6 and column 6, counting from 0 starting at the top left corner):

Draw the 7×7 finder patterns on the three corners and 1-module separators (which overwrites some timing modules):

Draw the grid of 5×5 alignment patterns (but skipping the three finder corners):

Draw temporary dummy format bits (adjacent to the finders):

Draw the two 6×3 version information blocks (adjacent to the finders):

6. Draw codewords and remainder

Compute the zig-zag scan (which starts from the bottom right corner) to visit all unfilled modules (i.e. skipping function modules):

Draw data/ECC modules according to the zig-zag scan order and bit values from the final sequence of codewords:

(For example, the codeword byte C5 produces the sequence of modules [black, black, white, white, white, black, white, black].)

7. Try applying each mask


The mask pattern (only affects non-function modules):

XOR the mask to the modules of data, ECC, and remainder:

Draw the actual format bits (adjacent to the finders):

8. Find penalty patterns

Horizontal runs of same color modules (each at least 5 long):

Vertical runs of same color modules (each at least 5 long):

2×2 boxes of same color modules:

Horizontal false finder patterns:

Vertical false finder patterns:

Balance of black/white modules:

Side length:
Total modules:
White modules:
Black modules:
Proportion black:
Deviation from half:

9. Calculate penalty points, select best mask

Mask RunP BoxP FindP BalP TotalP

Lowest total penalty points: Mask pattern

How penalties are calculated:

  • 3 points for each 5-module linear run of the same color, 4 points for each 6-module run, 5 points for each 7-module run, 6 points for each 8-module run, etc. Runs cannot overlap.

  • 3 points for each 2×2 box of the same color. Boxes can overlap.

  • 40 points for each false finder pattern. Finder patterns can overlap.

  • 0 points if the proportion of black modules is in the range [45%, 55%]; 10 points if within [40%, 60%]; 20 points if within [35%, 65%]; 30 points if within [30%, 70%]; etc.

This web application’s source TypeScript code (file 0, file 1) and compiled JavaScript code are available for viewing.

More info