Project Nayuki

QR Code generator library


This project aims to provide the best and clearest QR Code generator library. My primary goals are flexible options and absolute correctness. The secondary goals are compact implementation size and good documentation comments.

This work is an independent implementation based on reading the official ISO specification documents. I believe that my library has a more intuitive API and more concise implementation than competing libraries out there. The library is designed first in Java and then ported to JavaScript, Python, and C++. It is open source under the MIT License.

Live demo (JavaScript)

You can generate QR Code symbols conveniently on this web page, powered by the JavaScript version of this library.

Text string:
Error correction:
Border: modules
Scale: pixels per module
Output format:
Advanced: Version min/max: to
Mask pattern: (−1 for automatic)
QR Code:


Core features:

Manual parameters:

Optional advanced features (Java only):

Source code

My QR Code generator library is provided in multiple languages for your convenience, with essentially the same API structure and naming in every language. Regardless of the language used, the generated results are guaranteed to be identical because the algorithms are translated faithfully.

For my own convenience when designing and testing the code, the Java language version of the QR Code generator library is considered to be the master reference version. All the other language versions are ported from the Java version, with a balance between writing idiomatic code in the target language but also not deviating too much from the Java version’s design. When in doubt, please consult the Java version to read the more extensive documentation comments and to check what types and values are considered legal.

The full project repository is available at GitHub:


The library:,,
Optional advanced logic:
Runnable demo program:

Usage examples:

import io.nayuki.qrcodegen.*;

// Simple operation
QrCode qr0 = QrCode.encodeText("Hello, world!", QrCode.Ecc.MEDIUM);
BufferedImage img = qr0.toImage(4, 10);
ImageIO.write(img, "png", new File("qr-code.png"));

// Manual operation
List<QrSegment> segs = QrSegment.makeSegments("3141592653589793238462643383");
QrCode qr1 = QrCode.encodeSegments(segs, QrCode.Ecc.HIGH, 5, 5, 2, false);

This compact, no-dependency library is your one-stop shop for all your QR Code generation needs. To learn how to use the API, please read the demo program’s source code, and maybe skim the library code’s inline Javadoc comments.

For the following practical reasons, Java is my best choice for the reference version because it ensures a high degree of correctness and allows writing detailed documentation comments:

  • Static type checking prevents dumb typos in names and subtly incorrect arguments being passed (such as byte[] vs. BitBuffer). (Whereas Python and JavaScript don’t have static type checking.)
  • There is a strong and clear separation between public interfaces and private implementation details. (Whereas privacy is only a naming convention in Python, and feasible but hacky/ugly in JavaScript.)
  • Javadoc is expressive and has a consistent syntax. (Whereas Python, JavaScript, and C++ do not have single dominant syntax for documentation comments.)
  • Java has good standard libraries for file, image, and network handling, and the language is memory-safe. This makes it easier to build a correct application quickly. (Whereas C++ programming easily gets into third-party library frenzy and undefined behavior hell – even though it does have static typing and proper public/private just like Java.)
  • Only the Java version of my library contains the advanced segment encoder logic for kanji mode and optimal segment mode switching.

The library: qrcodegen.js
The demo on this page: qrcodegen-demo.js

Usage examples:

// Name abbreviated for the sake of these examples here
var QRC = qrcodegen.QrCode;

// Simple operation
var qr0 = QRC.encodeText("Hello, world!", QRC.Ecc.MEDIUM);
var svg = qr0.toSvgString(4);

// Manual operation
var segs = qrcodegen.QrSegment.makeSegments("3141592653589793238462643383");
var qr1 = QRC.encodeSegments(segs, QRC.Ecc.HIGH, 5, 5, 2, false);

The public interface (the set of available functions and constants) is summarized in the big block comment near the top of the library source file. Any function/variable not included in that comment is considered private and is subjected to change.

Although the low-level imperative code parts (e.g. loops, arithmetic) are virtually identical to the Java version, the organization of classes and methods looks quite different due to JavaScript’s use of closures to simulate objects. The documentation comments in the JavaScript version of the library is not as good as the Java version, and there is a higher risk of errors with respect to names and values.

Note that all private functions, methods, and fields are hidden as function-local variables so that it is impossible to access them from outside the library. This ensures that no external code depends on internal variables and APIs that might change in the future. On the other hand, all public fields and methods are writable, which means it is possible to (for example) reassign qrcodegen.QrCode to another value (please don’t do this).


The library:
Runnable demo program:

Also available as a package on PyPI: pip install qrcodegen

Usage examples:

from qrcodegen import *

# Simple operation
qr0 = QrCode.encode_text("Hello, world!", QrCode.Ecc.MEDIUM)
svg = qr0.to_svg_str(4)

# Manual operation
segs = QrSegment.make_segments("3141592653589793238462643383")
qr1 = QrCode.encode_segments(segs, QrCode.Ecc.HIGH, 5, 5, 2, False)

Python 2.7 and 3.x are supported. Please read the demo program’s source code to get a good idea of how to use this library. For further information, consult the big comment at the top of the library source file that summarizes all the public classes, functions, and methods available in the module.


The library: QrCode.hpp, QrSegment.hpp, BitBuffer.hpp, QrCode.cpp, QrSegment.cpp, BitBuffer.cpp
Runnable demo program: QrCodeGeneratorDemo.cpp

Usage examples:

#include <string>
#include <vector>
#include "QrCode.hpp"
using namespace qrcodegen;

// Simple operation
QrCode qr0 = QrCode::encodeText("Hello, world!", QrCode::Ecc::MEDIUM);
std::string svg = qr0.toSvgString(4);

// Manual operation
std::vector<QrSegment> segs =
QrCode qr1 = QrCode::encodeSegments(segs, QrCode::Ecc::HIGH, 5, 5, 2, false);

The code requires C++11 to compile due to numerous convenient features unavailable in C++03, such as better handling of temporary values and const instance fields. The code is unfortunately not suitable for embedded microcontroller environments (e.g. Arduino) due to the use of the heavyweight STL std::vector class and dynamic memory allocation.

QR Code technology overview

The QR Code standard defines a method to encode a string of characters or bytes into a grid of black and white pixels. The text could be numbers, names, URLs, et cetera. Because the standard uses a 2D barcode, it can store much more information than a traditional 1D barcode. To illustrate for comparison, a 1D barcode usually stores 10 to 20 digits, while a QR code often stores 50 textual characters. Note that a QR Code barcode simply represents static data – the barcode does not inherently cause an action to be executed.


Some of the frequently used official terminology have non-intuitive meanings, as summarized below:

QR Code
A popular international standard (symbology), created by Denso Wave, that specifies how messages are converted to barcodes.
QR Code symbol
A single 2D graphical barcode, which results from the QR Code generation process. Informally this is called a “QR code” (without using the word symbol) or a barcode.
A black or white pixel in a QR Code symbol. Note that a module can be scaled to occupy multiple pixels on a screen or in an image file.
A way of measuring the size of a symbol, from 1 to 40. Version 1 has 21×21 modules, version 2 has 25×25, ..., and version 40 has 177×177. Note that all 40 versions are defined in a single standard, and this term differs from the conventional meaning of the word version.
Indicates the revision of the QR Code standard. (The word model here corresponds with the conventional meaning of the word version.) Model 1 QR codes are outdated and essentially never seen. Model 2 QR codes are widespread and dominant. Model 2 also has an extension called Micro QR codes (not implemented in my library). Note that model 1 defines versions 1 through 14, whereas model 2 QR defines versions versions 1 through 40, allowing much more data capacity.

Generation procedure

The process (and high-level algorithm) for generating a QR Code symbol is as follows:

  1. Choose the text (Unicode string) or binary data (byte string) to encode.
  2. Choose one of the 4 error correction levels (ECL). A higher ECC level will yield a barcode that tolerates more damaged parts while preserving the payload data, but will tend to increase the version number (i.e. more modules in width and height).
  3. Encode the text into a sequence of zero or more segments. A segment in byte mode can encode any data, but using alphanumeric or numeric mode is more compact if the text falls into these subsets.
  4. Based on the segments to be encoded and the ECL, choose a suitable QR Code version to contain the data, preferably the smallest one.
  5. Concatenate the segments (which have headers and payload) and add a terminator. The result is a sequence of bits.
  6. Add padding bits and bytes to fill the remaining data space (based on the version and ECL).
  7. Reinterpret the bitstream as a sequence of bytes, then divide it into blocks. Compute and append error correction bytes to each block. Interleave bytes from each block to form the final sequence of 8-bit codewords to be drawn.
  8. Initialize a blank square grid based on the version number.
  9. Draw the function patterns (finders, alignment, timing, version info, etc.) onto the appropriate modules. This is formatting overhead to support the QR Code standard, and does not encode any user data.
  10. Draw the sequence of (data + error correction) codewords onto the QR Code symbol, starting from the bottom right. Two columns at a time are used, and the scanning process zigzags going upward and downward. Any module that was drawn for a function pattern is skipped over in this step.
  11. Either manually or automatically choose a mask pattern to apply to the data modules. If masking automatically, then all 8 possibilities are tested and the one with the lowest penalty score is accepted. Note that the format information is redrawn to reflect the mask chosen.
  12. We are now finished the algorithmic parts of QR Code generation. The remaining work is to render the newly generated barcode symbol as a picture on screen, or save it as an image file on disk.

Note that my QR Code generator library provides the logic to perform steps 3 through 11. The other steps must be performed by the user of the library.

Compared to competitors

qrcodegen by Project Nayuki (Java, JavaScript, Python, C++)
  • Relatively compact implementation – 1170 lines of code for the Java version (without QrSegmentAdvanced), 1000 lines for JavaScript, 820 lines for Python, 1260 lines for C++ (each version is independent, so it’s meaningless to add up all the line counts)
  • Contains as few tables of numerical constants as needed – unlike competitors, this implementation does not have tables of: data capacities per version, alignment pattern positions, error correction block sizes, expanded format and version bits, Reed-Solomon divisor polynomials, or finite field exp/log tables
  • The QR Code and helper objects are all immutable, thus simplifying user operation and reducing errors from accidental misuse of the API
  • Line counts include the generous amount of comments for functions and for blocks of statements
  • The extra advanced features (kanji mode, optimal segment mode switching) in the Java version cost another 270 lines of code and 110 lines of constants
  • The version reviewed was 9a832a200d27, dated 2016-04-22
qr.js by Kang Seonghoon (JavaScript)
  • About 800 lines of core code in the library
  • Code is quite concise, minimizing the size of constant tables and avoiding verbose logic
  • Includes generous comments explaining the overview of behavior
  • The organization and behavior of subfunctions (such as computing the number of bits and characters, and painting different sets of QR Code modules) are surprisingly similar to my design, despite the fact that he published one year earlier than me and I had never seen his code until months after I published my library
  • The code is more compact than mine in areas such as the bit buffer and segment encoding, because they are inlined into the QR Code generation workflow instead of being exported as freestanding modules
  • The version reviewed was 52f0409a22c5, dated 2015-04-11
qr.js by Alasdair Mercer (JavaScript)
  • About 1200 lines of core code in the library
  • qr.js: 800 lines for main QR encoding logic, 110 lines for numerical tables, 300 lines for image export
  • Code includes a good number of comments inside and outside functions
  • Only supports 8-bit segment encoding mode; generateFrame() is a 400-line monolithic function
  • The version reviewed was 18decea6ba9a, dated 2015-11-11
QR Code Generator by Kazuhiko Arase (JavaScript, others)
  • About 1840 lines of core code in the JavaScript library
  • qrcode.js: 860 lines of code for main QR encoding logic, 340 lines for numerical tables, 360 lines for HTML and GIF output, 280 lines for binary encoding utilities
  • Contains no comments at all to describe functions; sparsely contains low-level comments to describe chunks of logic statements
  • The author has ported the library to multiple languages, but with different levels of features. The JavaScript version appears to be the most feature-complete, the Java version has fewer features but more documentation comments, and others have less features and comments.
  • The version reviewed was 94f0023b802a, dated 2016-01-23
QR-Logo by Henrik Kaare Poulsen (JavaScript)
  • About 2900 lines of core code in the library
  • Supports encoding and decoding(!) QR Code symbols
  • qrcodedecode.js: 970 lines of code for an encoder with the typical features, 1100 lines for a decoder that can operate on imperfect images (i.e. not axis-aligned with whole-pixel module size), 410 lines for tables of numbers
  • reedsolomon.js: 420 lines of code for Reed-Solomon encoding, decoding syndrome calculation, error correction, polynomial arithmetic
  • The version reviewed was b3a77e8f0145, dated 2011-10-15
qrcode by Lincoln Loop (Python)
  • About 1300 lines of core code in the library
  • 420 lines for text accumulation, module drawing, terminal printing
  • 550 lines for tables of various constants, QR symbol penalty calculation, segment encoding logic, bit buffer class, block error correction and interleaving, bitstream formatting
  • 360 lines for finite field tables, error correction block sizes, polynomial class
  • Code documentation/comments is neglectfully sparse in most places, but has some good comments for the public methods of the QRCode class
  • The version reviewed was b79ab5b3e598, dated 2016-03-15
PyQRCode by Michael Nooner (Python)
  • About 2800 lines of core code in the library
  • 900 lines of code for segment encoding, bitstream formatting, ECC generation, module drawing, symbol penalty calculation; 500 lines for export logic to various image formats
  • 620 lines for mostly character encoding logic, some one-liner wrapper methods for exporting images, and long documentation comments
  • 750 lines of almost entirely numeric constants
  • Generally speaking the function-level documentation comments are long (and longer than my typical writing), there are comments every 5 or so lines within functions to describe the algorithmic processes (just like I do), but the implementation seems to use a lot of code just to implement basic behaviors
  • The version reviewed was 467f9a2a3c04, dated 2016-02-26

More info