Open source
Open-source QR code libraries
By Sam Moreton · updated 13 August 2026
10 min read · Updated 13 August 2026
Decide which problem you have first
Half the confusion in this space comes from treating one question as three. Sort yourself into a row before reading further:
| You want to | You need | Skip to |
|---|---|---|
| Turn data into a QR image in code | An encoder | Generating |
| Read a QR code from a camera or image | A decoder | Reading |
| Produce a styled, branded code | An encoder plus a renderer | Styling |
| Change where a printed code points, later | A service, not a library | When a library is the wrong tool |
Encoding is settled; rendering is where libraries differ
Every correct encoder produces the same module pattern for the same input, because ISO/IEC 18004 leaves no room for interpretation. So libraries do not really compete on the QR maths. They compete on output formats, styling, dependencies and licence. That is why the comparisons below say almost nothing about correctness.
Generating: JavaScript and TypeScript
| Library | Licence | Version | Best for |
|---|---|---|---|
qrcode | MIT | 1.5.4 | The default choice. Node and browser, PNG and SVG out, terminal output, tiny API. |
qr-code-styling | MIT | 1.9.2 | Styled codes: gradients, dot and corner shapes, embedded logos. Browser-oriented. |
qrcode-generator | MIT | 2.0.4 | A low-level encoder that hands you the module matrix and gets out of the way. Use when you are drawing the code yourself. |
If you just need a PNG in a Node script, qrcode is the answer and you can stop reading this section. Reach past it only when you want control over how the code is drawn.
What this site is built on, since you can check it
OpenQR uses qrcode-generator for the module matrix and qr-code-styling for the rendering, both MIT. That split is the pattern worth copying: let a well-tested encoder decide which modules are dark, and keep the drawing in a layer you control, because styling is where your requirements will keep changing.
Generating: Python, Go, C and Java
| Library | Language | Licence | Notes |
|---|---|---|---|
segno 1.6.6 | Python | BSD-3-Clause | No dependencies, and it covers Micro QR as well as standard QR. The more complete of the two Python options. |
qrcode 8.2 | Python | BSD | The familiar one. Renders through Pillow, so it brings an imaging dependency with it. |
go-qrcode | Go | MIT | Straightforward encoder, PNG out, no cgo. |
libqrencode | C | LGPL-2.1 | Fast, tiny, and packaged in essentially every Linux distribution as the qrencode command. Read the licence note below. |
zxing | Java | Apache-2.0 | Generates and reads. The reference implementation on Android for many years. |
For a command line rather than a codebase, qrencode is hard to beat: it is one apt install or brew install away, it writes PNG, EPS and ANSI, and it makes generating a few thousand codes from a shell loop a one-liner.
Reading: decoding a QR code
| Library | Platform | Licence | Notes |
|---|---|---|---|
jsqr 1.4.0 | Browser, JS | Apache-2.0 | Pure JavaScript, takes raw image data. Small and dependency-free, so it is the usual pick for a webcam scanner. |
@zxing/library 0.23.0 | Browser, JS | Apache-2.0 | A TypeScript port of ZXing. Handles many barcode symbologies, not just QR. |
zxing | Java, Android | Apache-2.0 | The long-standing reference decoder. |
OpenCV QRCodeDetector | C++, Python | Apache-2.0 | Already present if you are doing other computer vision. Good at finding a code in a messy photograph. |
Worth knowing before you pick: decoders disagree with each other, and they disagree most on exactly the codes people most want to make. Heavy styling, an oversized logo, inverted colours or a low print resolution can leave a code that one decoder reads instantly and another refuses. If you are validating codes programmatically, test against more than one decoder, and treat the strictest as the one that matters, because you do not get to choose which app your customer opens.
Licences: the part that causes trouble later
Most of these are MIT, BSD or Apache-2.0, which are permissive: use them in closed and commercial products, keep the notice, carry on. Two details are worth an extra minute.
libqrencodeis LGPL-2.1, not MIT. Linking to it dynamically from a closed product is the intended and unproblematic case. Static linking, or vendoring it into a binary you ship, brings obligations that the permissive libraries do not have. If you are shipping an embedded or desktop binary, this is the one to raise before you ship, not after.- Apache-2.0 includes an explicit patent grant and a requirement to state changes you make. Some corporate policies prefer it over MIT for exactly the first reason. Neither is a problem; they are just different paperwork.
A separate question people conflate with this: the licence of the library never touches the codes it produces. A QR code is your data rendered as a pattern, so it is not something the library author can licence. Generate commercially with any of the above.
When a library is the wrong tool
Every library on this page produces static codes. The data is encoded in the pattern, which is why static codes never expire and work with no server. It is also why no library can give you these:
- Changing the destination after printing. That requires the code to point at a redirect you control, which is a service somebody has to keep running. See static vs dynamic QR codes.
- Scan analytics. A static code is not observable. Nothing phones home when it is scanned, by design, so there is nothing to count.
- Short, readable links. Also a redirect service.
If you need any of those, you need a service behind the code, and then the build-or-buy question is about running a redirector with the uptime a printed code deserves. OpenQR's REST API and MCP server cover it if you would rather not, and are free to use. If you would rather run everything yourself, the self-hosting guide is honest about which half you can and cannot take with you.
And if you are not building software at all, a library is a lot of ceremony for one code. The generator on this site does it in a browser tab with no account, and it is open source too.