qrcode.react
qrcode.react is a small React component library that turns a string, or an array of text segments, into a QR code rendered as SVG or Canvas. It handles QR version selection, four error-correction levels, colors, quiet-zone margins, accessible titles, and an optional centered image. It is a renderer only: it does not scan codes, validate the destination, shorten URLs, track scans, or provide a non-React API. SVG is the documented default choice, while Canvas is available for cases that specifically need a bitmap-like DOM surface.
A focused, low-cost choice for ordinary QR display in React, especially when SVG output is enough. Do not install it for scanning, non-React code, binary encoding, or heavily styled marketing codes.
Use it if
- You need to render a QR code inside an existing React 16.8 through 19 application
- You want an SVG component that accepts ordinary className, style, and DOM props
- You need a centered logo with optional module excavation and explicit cross-origin handling
- You want typed control over size, colors, margins, minimum QR version, and error correction
- You are not using React: React is a peer dependency, and the package exports React components rather than a framework-neutral encoder
- You need to scan or decode QR codes: the README describes generation only, with no camera, image-decoding, or validation API
- You need binary segments or optimized Kanji mode: the README says encoding is text-only and explicitly says optimized Kanji encoding is unsupported
- You expect a standards-safe quiet zone by default: marginSize defaults to 0 even though the README says the QR specification requires 4 modules
- You need a responsive Canvas that can be enlarged freely: the README warns that CSS scaling beyond the size prop produces a blurry result
Setup reality
Installation is one command, but React is not bundled. Version 4.2.0 declares React 16.8, 17, 18, or 19 as a peer, so this only belongs in a React tree. Import QRCodeSVG or QRCodeCanvas by name; there is no default component in the documented API. The first production surprise is the quiet zone: marginSize defaults to 0, while the README says the QR specification requires 4 modules. Set marginSize={4} unless your surrounding layout supplies verified whitespace. The older includeMargin prop is deprecated in v4 and is planned for removal. SVG is the easier responsive option. Canvas is rendered at extra device pixels for sharpness, then sized with inline CSS; overriding width or height beyond the numeric size prop can blur it, so update size when the container changes. Logo images need explicit pixel dimensions and usually excavate: true so covered modules become background. For Canvas export, a remote logo can taint the canvas unless the image server sends suitable CORS headers and imageSettings.crossOrigin is set correctly. The value API encodes text, not arbitrary byte buffers, and arrays create separate text segments rather than multiple QR codes. Always test the final code on several physical scanners, especially after adding a logo, changing contrast, lowering margins, or packing a long value.
Patterns
Render the recommended SVG formrender-svg
import { QRCodeSVG } from 'qrcode.react';
export function PaymentCode({ url }) {
return <QRCodeSVG value={url} marginSize={4} title="Payment link" />;
}SVG is the README's general recommendation. marginSize defaults to 0, so set the four-module quiet zone explicitly.
Render to Canvasrender-canvas
import { QRCodeCanvas } from 'qrcode.react';
<QRCodeCanvas
value="https://example.com/check-in"
size={256}
marginSize={4}
/>;Do not enlarge the Canvas beyond size using CSS alone; the README warns that scaling past the rendered size looks blurry.
Reserve more recovery capacityset-error-correction
<QRCodeSVG
value={ticketUrl}
level="H"
size={192}
marginSize={4}
/>;Higher error correction makes a more complex code. The supported levels are L, M, Q, and H, with L as the default.
Place a logo in the centerembed-logo
<QRCodeSVG
value={profileUrl}
level="H"
marginSize={4}
imageSettings={{
src: '/brand-mark.svg',
width: 32,
height: 32,
excavate: true,
}}
/>;excavate replaces modules under the image with the background color. Scan-test the result because the component cannot judge whether a logo is too large.
Download a Canvas QR code as PNGexport-canvas-png
import { useRef } from 'react';
import { QRCodeCanvas } from 'qrcode.react';
function DownloadableCode({ value }) {
const wrapRef = useRef(null);
const download = () => {
const canvas = wrapRef.current.querySelector('canvas');
const link = document.createElement('a');
link.download = 'qr-code.png';
link.href = canvas.toDataURL('image/png');
link.click();
};
return <div ref={wrapRef}><QRCodeCanvas value={value} size={512} marginSize={4} /><button onClick={download}>Download</button></div>;
}A remote embedded image can taint the Canvas and make toDataURL throw unless its server permits CORS.
Make SVG output fit its containerstyle-responsive-svg
<QRCodeSVG
value={url}
size={256}
marginSize={4}
style={{ width: '100%', height: 'auto', maxWidth: 256 }}
aria-label="QR code for this page"
/>;Extra props pass through to the underlying SVG. Keep the rendered code square and preserve visible whitespace around it.
Apply high-contrast brand colorsset-colors
<QRCodeSVG
value={url}
fgColor="#172554"
bgColor="#ffffff"
marginSize={4}
/>;Both values accept CSS colors, but the package does not check contrast. Physical scan testing is still required.
Split text into optimized segmentsencode-segments
<QRCodeSVG
value={['ORDER-', String(orderNumber), '-EU']}
marginSize={4}
/>;Since v4.1, an array represents separately encoded text segments. It does not render several codes and does not accept binary segments.
Set a minimum QR versioncontrol-version
<QRCodeSVG
value={payload}
minVersion={5}
boostLevel={false}
marginSize={4}
/>;minVersion accepts 1 through 40 and only sets a lower bound. Disabling boostLevel prevents automatic error-correction upgrades that fit the same version.
Load a cross-origin logo for Canvas exportconfigure-image-cors
<QRCodeCanvas
value={url}
size={384}
marginSize={4}
imageSettings={{
src: 'https://cdn.example.com/logo.png',
width: 48,
height: 48,
excavate: true,
crossOrigin: 'anonymous',
}}
/>;The CDN must return a matching Access-Control-Allow-Origin header. Setting crossOrigin cannot fix a server that denies the request.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| react-qr-code | npm | You want an even narrower React SVG component with fewer presentation options |
| qrcode | npm | You need a framework-neutral encoder that can produce data URLs, buffers, files, Canvas, or terminal output |
| qr-code-styling | npm | You need branded dots, corner shapes, gradients, and downloadable browser output |