Skip to content
UseQR
ESC

Jump to

MOVEOPEN50 places

Developers & agents

ZXing vs quirc vs zbar

ZXing is the reference family: the Java original is in maintenance mode but zxing-cpp is actively developed with bindings for Python, WebAssembly and mobile. zbar is a fast C decoder kept alive by a community fork. quirc is a few thousand lines of dependency-free C for embedded targets. For new projects, zxing-cpp is the safe default.

View as MarkdownPaste this page into any AI assistant. It is plain, portable Markdown.

Three engines, three philosophies

Almost every QR scanner you have ever used sits on one of three open-source decoding engines. They embody different trade-offs:

ZXing family zbar quirc
Origin Java, Google 20% project C, originally for Linux webcams C, written for embedded use
Licence Apache-2.0 LGPL-2.1 ISC
Active development zxing-cpp: yes; Java: maintenance mode community fork low-volume but alive
Codebase size large medium a few thousand lines, zero dependencies
Symbologies many 1D + 2D many 1D + 2D QR only
Bindings Python, WASM, iOS, Android, .NET Python (pyzbar), Perl, more C API; ports exist

ZXing: the reference that got rewritten

ZXing ("zebra crossing") is the historic reference decoder, for years, "does it decode in ZXing" was the practical definition of a valid QR code. The Java project announced maintenance mode, but the story did not end there: zxing-cpp, a from-scratch C++ port, became the actively developed centre of gravity, with official Python bindings (pip install zxing-cpp), a WebAssembly build (zxing-wasm) and mobile wrappers.

Its decoding is the most thorough of the three: it handles mirrored codes, inverted polarity, damaged finder patterns and a tryHarder mode that trades latency for recovery. That thoroughness is why UseQR standardised on zxing-wasm everywhere a decode happens: the browser scanner, POST /api/v1/decode, the verify endpoint and the CI suite all run the same engine, so "scannable" means the same thing in every context.

zbar: fast, old, forked

zbar is a C library from the webcam era, and its architecture (a streaming scanner that processes video lines) makes it very fast on modest hardware. It powers the zbarimg CLI and Python's pyzbar, and it remains a perfectly good decoder for clean, well-lit images. The honesty: the original project stalled over a decade ago, and maintenance lives in a community fork. Its LGPL licence also needs a moment's thought in statically linked or app-store contexts, where Apache/ISC engines are simpler.

quirc: the embedded specialist

quirc does one thing: decode QR codes, in portable C, in a few thousand lines, with no dependencies and modest, predictable memory use. That makes it the default choice on microcontrollers and camera firmware where zxing-cpp will not fit. It supports QR only, no 1D barcodes, no Micro QR, and its tolerance of blur, damage and perspective is the narrowest of the three. On an ESP32 reading codes off a conveyor at fixed distance, that is fine; in a general-purpose phone scanner it is not.

On benchmarks

Published decoder benchmarks age badly and depend enormously on the test corpus: resolution, blur, damage, lighting, angle. Rather than quote numbers we cannot stand behind: the ranking that holds across most corpora is that zxing-cpp recovers the most marginal codes, zbar is competitive on clean images and cheap on CPU, and quirc trades robustness for size. If decode margin matters to you, measure it on your images: the decode-verify loop is exactly that measurement, run continuously.

Recommendations

  • New project, any platform: zxing-cpp (or zxing-wasm in JS). Active, permissive, thorough.
  • Legacy pipeline already on zbar: no urgent reason to move; it still decodes.
  • Embedded, kilobytes matter: quirc, and control your imaging conditions.
  • No local install possible: the keyless decode API runs zxing for you.

FAQ

Is ZXing dead?

The original Java project is in maintenance mode, not deleted, but new development happens in zxing-cpp, a C++ rewrite with Python, WebAssembly, iOS and Android bindings that is actively maintained. New projects should target zxing-cpp.

Which QR decoder is the most accurate?

Across most image sets, zxing-cpp recovers the most damaged and marginal codes, especially with tryHarder enabled. Exact rates depend heavily on your images, so test with your own corpus rather than trusting published benchmarks.

What is quirc used for?

Embedded systems. quirc is a few thousand lines of dependency-free ISC-licensed C with modest memory needs, which makes it the standard choice for microcontrollers and firmware where larger engines will not fit. It decodes QR codes only.

Does zbar still work?

Yes. The original project stalled long ago but a community fork maintains it, and tools built on it (zbarimg, pyzbar), still decode reliably. Its LGPL licence deserves a check in statically linked commercial builds.

Try it: free, no signup

  • QR code libraries compared, A map of the QR library ecosystem: generation and decoding, by language, with licences and honest maintenance status. Pick by use case, not by stars.
  • Decode a QR code programmatically, Read QR codes from images in code: POST bytes or a URL to the keyless decode API, or decode locally with zxing-cpp, zbar or pyzbar. Snippets included.
  • Building a decode-verify loop, The engineering pattern that proves a QR code scans: render, rasterise, decode with a real decoder, compare. How to build it, and the report fields that matter.
  • A free QR code API with no key, UseQR's REST API needs no signup, no API key and no SDK. GET /api/v1/qr?data=hello returns a PNG. The shortest form is /q/hello.png, which drops straight…