qr-code-styling
A JavaScript/TypeScript library for generating richly styled QR codes with embedded logos, gradients, and custom dot shapes.
Repository Health
Technical Analysis
qr-code-styling wraps the qrcode-generator encoding library with a full rendering and styling layer, letting developers produce QR codes that look like branded graphics instead of plain black-and-white grids. It renders to either an HTML canvas or an SVG element, and supports independently configurable colors, gradients, and shapes for the data dots, corner squares, corner dots, and background, plus an embeddable center logo/image with margin and background-hiding controls.
Beyond the browser, the library runs on Node.js by accepting an injected node-canvas or jsdom instance, so QR codes can be generated server-side for things like PDF generation pipelines or batch ticket/invoice rendering. An applyExtension hook exposes the raw SVG element for post-processing (borders, watermarks, custom shapes) before the code is rendered or downloaded, and getRawData/download cover exporting to PNG, JPEG, WebP, or SVG.
What You Get
- A
QRCodeStylingclass you instantiate with an options object and append to any DOM container - Independent styling controls for dots, corner squares, corner dots, and background, each with solid color or linear/radial gradient support
- Logo/image embedding with configurable size, margin, cross-origin handling, and an option to hide background dots behind the image
- Canvas and SVG render targets, selectable per instance, with PNG/JPEG/WebP/SVG export via
getRawDataordownload - Node.js support via injected
node-canvas/jsdominstances for server-side generation - An
applyExtensionhook for injecting custom SVG post-processing (e.g. borders) via community plugins like qr-border-plugin
Common Use Cases
- Adding a branded QR code (with company logo and brand colors) to a marketing landing page
- Generating QR codes for payment links, vCards, or Wi-Fi credentials with custom visual styling
- Server-side QR code generation for PDF tickets, invoices, or badges via the Node.js canvas/jsdom path
- Building React/Vue/Angular/Next.js UI components that render and let users download styled QR codes
Under The Hood
Architecture
The QRCodeStyling class (src/core/QRCodeStyling.ts) is a thin orchestrator: its constructor merges caller options over the library’s defaults (QROptions.ts) via a deep-merge/sanitize pass, then delegates the actual QR matrix encoding to the qrcode-generator dependency. Rendering itself lives in QRSVG, which walks the encoded matrix and builds SVG geometry using dedicated figure classes (QRDot, QRCornerSquare, QRCornerDot) for the data dots, corner squares, and corner dots respectively, each supporting solid color or gradient fills. When the canvas render target is selected, the class serializes the generated SVG to a data URI and draws it onto either a browser <canvas> or an injected node-canvas context rather than maintaining a separate canvas-drawing code path — SVG generation is the single source of truth for QR geometry. This means the figure classes and the canvas-rasterization step are tightly coupled: a change to how geometry is expressed would need to propagate through both paths.
Tech Stack
Written in TypeScript under strict compiler settings (strict null checks, no implicit any, no unused locals) and built with Webpack into both a browser UMD-style bundle and a .common.js build for Node consumers. The only runtime dependency is qrcode-generator for QR matrix encoding; canvas and jsdom are dev dependencies used to support and test the optional Node.js rendering path, not bundled into the published package. Testing runs on Jest with ts-jest and a fixed jsdom environment; linting uses ESLint’s flat config with typescript-eslint and Prettier for formatting. GitHub Actions workflows automate version bumps and npm publishing on release.
Code Quality
Most core modules — the main QRCodeStyling/QROptions classes, the tools (merge, getMode, calculateImageSize), and the constants — have accompanying Jest test files, with coverage collection enabled in the Jest config. Inline comments are sparse throughout; the codebase relies on TypeScript’s type system rather than prose for self-documentation. Error handling is informal in places (plain thrown strings rather than typed error classes for invalid state), which is a rougher edge for consumers trying to catch specific failure modes. Style is enforced consistently via ESLint and Prettier.
API Design
A single options object covers the whole surface — dimensions, data, per-element styling, embedded image, and optional Node canvas/jsdom injection — with sensible defaults, so a minimal working QR code needs only a data string. Restyling an existing instance is a one-line update(partialOptions) call that deep-merges onto current state instead of requiring re-instantiation. The applyExtension hook is a genuinely useful DX touch: it hands the raw SVG element and resolved options to a plain function, letting consumers (or third-party packages like qr-border-plugin) layer decorative extensions without forking the library. Node support is opt-in via constructor injection rather than a separate API, keeping one surface for both browser and server use — solid, ergonomic design though the underlying styling concepts are comparable to other QR-styling libraries in the ecosystem rather than something structurally novel.
Used by 3 apps in this directory
Formbricks
Forms Surveys · Marketing · Analytics
Open-source experience management platform for in-app, website, email, and link surveys — privacy-first and fully self-hostable.
OpenStatus
Monitoring · Devops
Open-source status pages and uptime monitoring with global synthetic checks, monitoring-as-code, and AI agent integration via MCP.
Sink
Bookmarks Archiving · Analytics
Serverless link shortener with real-time analytics, powered by Cloudflare