react-qrcode-logo

React component and headless API for rendering customizable QR codes with an embedded logo.

Library
npm
v4.1.0
600stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
40/100Fair
Development Activity28
Maintenance0
Community44
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
65/100Good
Architecture82
Code Quality45
Innovation78
Learning Curve55

react-qrcode-logo is a TypeScript React component that renders QR codes to an HTML canvas, with built-in support for embedding a logo image, customizing colors, module styles, and the shape of the three positional “eye” patterns. Beyond the <QRCode /> component, it exposes a headless rendering API — generateCanvas, generateDataURL, generateBlob, and downloadQRCode — so QR codes can be generated and exported without mounting any component, useful for previews, uploads, or composing the QR into a larger canvas.

The library wraps the qrcode-generator encoding package and adds its own canvas-drawing layer for logo placement, opacity, padding shapes, and per-eye radius/color customization, along with a hand-rolled deep-equality check that governs when the component re-renders.

What You Get

  • A <QRCode /> React component that renders directly to a <canvas> element, including automatic device-pixel-ratio scaling for crisp output on high-DPI screens.
  • Four standalone async functions (generateCanvas, generateDataURL, generateBlob, downloadQRCode) for producing a QR code outside of a mounted React tree.
  • Per-eye customization of the three positional patterns’ color and corner radius, independent of the rest of the QR modules.
  • Logo embedding with configurable width/height/opacity, square or circular padding, and an option to excavate QR modules directly behind the logo so it doesn’t obscure decodable cells.
  • Three QR rendering styles — squares, dots, and fluid — selectable via a single qrStyle prop.

Common Use Cases

  • Branded marketing QR codes - marketing teams embed a company logo into a QR code linking to a landing page or app store listing.
  • Downloadable QR assets in dashboards - a SaaS product renders a QR code in-app and lets the user download it as a PNG/JPG/WebP file via the download() method or downloadQRCode() function.
  • Server-composed QR previews - an app uses generateDataURL or generateBlob to produce a QR code for upload or email embedding without mounting a component.
  • Custom-styled QR codes for print collateral - designers use qrStyle: 'fluid' or 'dots' plus custom eyeColor/eyeRadius to match a QR code to a print piece’s visual identity.

Under The Hood

Architecture The library separates concerns cleanly into four files: QRCode.tsx (a thin React class component wrapping a canvas ref), renderer.ts (the pure headless rendering logic — renderQRCodeToCanvas plus the public generateCanvas/generateDataURL/generateBlob/downloadQRCode functions), and utils.ts (deep-equality, mime-type, and download-trigger helpers). The React component delegates all drawing to renderQRCodeToCanvas and limits itself to lifecycle wiring (componentDidMount/componentDidUpdate calling an internal update()) plus a custom shouldComponentUpdate built on the hand-rolled deepEqual helper, which replaced a former lodash.isequal dependency. Because the entire rendering engine is already exposed as a framework-agnostic standalone API, swapping the UI layer (or adding a wrapper for another framework) would touch only QRCode.tsx, while changes to the core drawing algorithm are isolated in renderer.ts and never touch component lifecycle code.

Tech Stack Written in TypeScript and compiled to dual CJS/ESM output via two separate tsc invocations (tsconfig.cjs.json/tsconfig.esm.json) rather than a bundler — a minimal, dependency-light build setup. The only runtime dependency is qrcode-generator, which performs the underlying QR data encoding and error correction; every visual feature (logo, eye styling, dot/fluid rendering styles) is layered on top of that encoder’s raw module grid. React and ReactDOM are peer dependencies (>=18.0.0), and the project documents that consumers on React <18 must stay on an older major version since it dropped ReactDOM.findDOMNode for ref-based canvas access. Storybook (@storybook/react-vite) provides interactive component documentation rather than serving as a test runner.

Code Quality There is no automated test suite — the test script is a stub that exits with an error, and no test files exist anywhere in the repository. Error handling is deliberately conservative: logo loading is wrapped in a try/catch inside renderQRCodeToCanvas, and a failed load is only logged as a warning so a broken logo URL degrades to a plain QR code instead of crashing the render. Naming is consistent and descriptive, and the codebase is strict TypeScript with exported types for every public option (QRRenderOptions, CornerRadii, EyeColor, FileType). No linter/formatter configuration or CI workflow is present in the repo, and the README explicitly asks contributors to preserve existing code style rather than reformatting.

API Design The public API is intentionally small and symmetric: the same options shape drives both the mounted <QRCode /> component and the four standalone functions, so switching between rendering in React and generating headlessly for export requires no reshaping of props — only the default pixel ratio differs between the two paths, and that distinction is called out directly in code comments. A single qrStyle prop switches between three rendering styles, and per-eye customization accepts either a scalar or a per-eye array, letting simple cases pass one value while advanced cases override each eye independently. Getting started requires one import and one JSX line, with sensible defaults for every other prop, and the imperative download() method is exposed cleanly through a component ref rather than requiring manual canvas plumbing.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search