QR Code
From-scratch, zero-dependency QR generator rendered as pure scalable SVG
Preview
Installation
Usage
Examples
Dot styles
dotStyle controls how data modules are drawn: "square" (default), "circle", or "rounded". The rounded style is neighbor-aware — runs of adjacent modules merge into continuous "snake" shapes while isolated modules become full dots.
Custom finders
The three finder patterns (the large corner "eyes") are styled independently from the data modules. Pass a single finder object to style all three, or a [topLeft, topRight, bottomLeft] tuple to style each. The outer ring and inner eye each take their own style and color.
With a logo
Pass a logo to embed an image (or any React element) in the center. The modules behind it are cleared and a quiet area is knocked out so the symbol stays scannable. When a logo is present the error correction level is automatically raised to "H" (≈30% recovery) unless you explicitly request "Q" or "H" yourself.
Export & download
The component exposes an imperative handle via ref with toSVGString(), toDataURL(), and getMatrix(). toDataURL() renders PNG or JPEG through an offscreen canvas at export time (the display itself is always pure SVG), or returns a vector SVG data URL with type: "svg".
API Reference
QRCode is an original composable — there is no underlying Base UI primitive. The QR encoder is implemented from scratch per ISO/IEC 18004, supporting Numeric, Alphanumeric, and Byte (UTF-8) modes across versions 1–40 and all four error correction levels, with automatic mode, version, and mask selection. The symbol is rendered entirely as SVG <path> elements, so it scales crisply at any size.
Props
QRCode
Renders an <svg> element and accepts any native SVG prop (className, style, aria-*, data-*, etc.) in addition to those below. The ref exposes a QRCodeHandle rather than the DOM node.
QRCodeHandle
The object exposed through ref.
Utilities
These named exports are framework-agnostic and tree-shakeable.
Notes
- Pure SVG. The display is rendered entirely as SVG paths — no canvas and no raster images — so it stays sharp at any resolution. A canvas is used only momentarily inside
toDataURL()to produce PNG/JPEG bytes. - Logos and scannability. Keep
logoSizemodest (≤0.3) and prefer a lightbackgroundbehind the logo. The automatic"H"error correction compensates for the cleared center, but very large logos can still defeat a scanner. toSVGString()and React-element logos. Image (src) logos are serialized into the string output; arbitrary React-element logos are not (only the knockout area is). Use an image logo when you need identical string/DOM output.- Cross-origin logos and PNG/JPEG export. Rasterizing a code whose logo points to another origin would taint the canvas.
toDataURL()automatically fetches and inlines a cross-origin logo before rasterizing (this works only if the image host sends CORS headers); if it can't, it throws a clear error. Prefer same-origin or data-URI logos, or export withtype: "svg". For raster export, set explicitforeground/backgroundcolors —currentColorresolves to black during rasterization. - Styling hook. The root carries
data-slot="qr-code";foregrounddefaults tocurrentColorso the code themes with surrounding text.