A lightweight, dependency-free library for generating highly customizable QR codes in browser environments. Leverage SVG to create stunning QR codes with unique designs and embedded logos. Fully documented for Angular and React, with no dependencies and just 40 kB after minification.
- 🚀 Features
- 📦 Installation
- 💻 Usage
- 📋 API Documentation
- 📚 Examples
- ✋ FAQ
- 📝 Contributing
- ⚖️ License
- QR Code Shapes: Choose between square or circle designs.
- Matrix Pixels: Customize pixel shapes like squares, circles, stars, and more.
- Eyes & Eye Frames: Fully customize the shape and color of the eyes.
- Logo Embedding: Add logos with adjustable size, background, and padding.
- Alignment Patterns: Unique patterns for larger QR codes.
- Colors & Gradients: Apply solid colors or various gradients to all elements.
- Backgrounds: Set solid colors or use background images.
- Timing Lines: Customize timing lines with different shapes and colors.
- Data Support: Encode URLs, text, emails, phones, SMS, geolocations, WiFi credentials, and more.
- Error Correction: Choose from LOW, MEDIUM, QUARTILE, or HIGH error correction levels.
- Encoding Modes: Supports Numeric, Alphanumeric, Byte, and Kanji modes.
- Declarative API: Use a simple JSON-based API to customize QR codes.
- Lightweight: Only 40 kB after minification, with no external dependencies.
- Browser Support: Works seamlessly in modern browsers and devices.
- Responsive: Fully scalable QR codes using SVG.
- Standards Compliant: Adheres to the ISO/IEC 18004 QR Code specification.
Install the library using npm or yarn:
npm install custom-qrcode-browser
# or
yarn add custom-qrcode-browser
Create a new Angular component to render the QR code:
import {
Component,
OnChanges,
Input,
ViewChild,
ElementRef,
SimpleChanges,
} from "@angular/core";
import { QrCodeGenerator, IQrData, QrOptions } from "custom-qrcode-browser";
@Component({
selector: "app-custom-qr-code",
standalone: true,
template: `<svg #svgElement></svg>`,
})
export class CustomQrCodeComponent implements OnChanges {
@Input() config!: QrCodeConfig;
@ViewChild("svgElement", { static: true })
svgElement!: ElementRef<SVGSVGElement>;
ngOnChanges(changes: SimpleChanges): void {
if (changes.config) {
this.generateQrCode();
}
}
private generateQrCode(): void {
if (this.svgElement?.nativeElement) {
const qrCodeCore = QrCodeGenerator(
this.svgElement.nativeElement,
this.config,
);
qrCodeCore.generateSvg();
}
}
}
Object declaration in html is just for the example. See more on example.
<app-custom-qr-code
[config]="{
data: {
type: 'Url',
data: { url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' }
},
options: {
sizeRatio: 1,
errorCorrectionLevel: 'HIGH',
shapes: { qrCode: { type: 'Circle' } }
}"
></app-custom-qr-code>
import React, { useRef, useEffect } from "react";
import { QrCodeGenerator, QrCodeConfig } from "custom-qrcode-browser";
const QrCode: React.FC<QrCodeConfig> = (qrCodeConfig) => {
const svgRef = useRef<SVGSVGElement | null>(null);
useEffect(() => {
if (svgRef.current) {
const qrCodeCore = QrCodeGenerator(svgRef.current, qrCodeConfig);
qrCodeCore.generateSvg();
}
}, [qrCodeConfig]);
return <svg ref={svgRef} />;
};
export default QrCode;
See more on example.
const Example: React.FC = () => (
<div style={{ width: 300 }}>
<QrCode
data={{
type: "Url",
data: { url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ" },
}}
options={{
sizeRatio: 1,
errorCorrectionLevel: "HIGH",
shapes: { qrCode: { type: "Circle" } },
}}
/>
</div>
);
export default App;
Describes the different kinds of information that can be scanned and interpreted by QR code readers.
const data: IQrData = {
type: "Text", // or 'Url', 'Email', etc.
data: {
/* specific data fields */
},
};
-
Text
type: 'Text', data: { value: string; // Any text string }
-
Url
type: 'Url', data: { url: string; // A valid URL }
-
Email
type: 'Email', data: { email: string; // Recipient email address copyTo?: string; // CC email address (optional) subject?: string; // Email subject (optional) body?: string; // Email body content (optional) }
-
GeoPos
type: 'GeoPos', data: { lat: number; // Latitude lon: number; // Longitude }
-
Bookmark
type: 'Bookmark', data: { url: string; // Bookmark URL title: string; // Bookmark title }
-
Wifi
type: 'Wifi', data: { authentication?: 'WEP' | 'WPA' | 'nopass'; // Authentication type ssid?: string; // Network SSID psk?: string; // Password hidden?: boolean; // Hidden network flag }
-
Phone
type: 'Phone', data: { phoneNumber: string; // Phone number }
-
SMS
type: 'SMS', data: { phoneNumber: string; // Recipient phone number subject?: string; // Message content (optional) isMMS?: boolean; // Set true for MMS, false for SMS (default) }
-
BizCard
type: 'BizCard', data: { firstName?: string; secondName?: string; job?: string; company?: string; address?: string; phone?: string; email?: string; }
-
VCard
type: 'VCard', data: { name?: string; company?: string; title?: string; phoneNumber?: string; email?: string; address?: string; website?: string; note?: string; }
-
MeCard
type: 'MeCard', data: { name?: string; address?: string; phoneNumber?: string; email?: string; }
-
Event
type: 'Event', data: { uid?: string; stamp?: string; organizer?: string; start?: string; // Format: YYYYMMDDTHHmmss end?: string; // Format: YYYYMMDDTHHmmss summary?: string; }
-
GooglePlay
type: 'GooglePlay', data: { appPackage: string; // App package name }
Describes the different options available to customize QR codes.
const options: QrOptions = {
sizeRatio: 0.8,
errorCorrectionLevel: "HIGH",
shapes: {
/* shape configurations */
},
};
-
sizeRatio:
number
(between 0 and 1)Defines the size ratio of the QR code relative to its container.
-
errorCorrectionLevel:
'LOW' | 'MEDIUM' | 'QUARTILE' | 'HIGH'
Error correction level; higher levels can restore more data if the code is damaged.
-
shapes:
QrShapesConfig
Customize the shapes of various QR code elements. See below for more details.
-
shapes.qrCode
Shape of the overall QR code.
shapes: { qrCode: { type: "Square" | "Circle"; seed?: number; // Optional: used to vary randomness added pixel in Circle type } }
-
shapes.matrixPixel
Shape of the individual pixels in the QR code matrix. See
QrPixelShapeConfig
andQrColorConfig
for details.shapes: { matrixPixel: { pixelShape: QrPixelShapeConfig; color?: QrColorConfig; } }
-
shapes.eye
Shape of the eyes (the three corner elements). See
QrColorConfig
for details.shapes: { eye: { type: 'Square' | 'Circle' | 'Rhombus'; cornerRadius?: number; // Between 0 and 1, only for 'Square' type color?: QrColorConfig; }; }
-
shapes.eyeFrame
Shape of the eye frames. See
QrPixelShapeConfig
andQrColorConfig
for details.shapes: { eyeFrame: { type: "Square" | "Circle"; pixelShape: QrPixelShapeConfig; color?: QrColorConfig; } }
-
shapes.logo
Embed a logo in the QR code. See
QrColorConfig
for details.shapes: { logo: { type: 'Circle' | 'Square' | 'Rhombus'; image?: string | null; // SVG or image URL sizeRatio?: number; // Between 0 and 1 padding?: number; // In pixels color?: QrColorConfig; }; }
-
shapes.timingLine
Customize the timing lines. See
QrPixelShapeConfig
andQrColorConfig
for details.shapes: { timingLine: { pixelShape: QrPixelShapeConfig; color?: QrColorConfig; } }
-
shapes.background
Background options for the QR code. See
QrColorConfig
for details.shapes: { background: { image?: string; // Image URL color?: QrColorConfig; // Background color }; }
-
shapes.alignmentPattern
Shape of the alignment patterns for larger QR codes. See
QrPixelShapeConfig
andQrColorConfig
for details.shapes: { alignmentPattern: { type: "Square" | "Circle"; pixelShape: QrPixelShapeConfig; color?: QrColorConfig; } }
Describes the different color options available for QR code elements.
const color: QrColorConfig = {
type: "Solid",
value: "#000000",
};
-
Solid
type: 'Solid', value: string; // Any valid CSS color value
-
LinearGradient
type: 'LinearGradient', colors: Array<[number, string]>; // e.g., [[0, 'red'], [1, 'blue']] orientation: 'Horizontal' | 'Vertical' | 'LeftDiagonal' | 'RightDiagonal';
-
RadialGradient
type: 'RadialGradient', colors: Array<[number, string]>; radius: number; // Between 0 and 1
-
SweepGradient
type: 'SweepGradient', colors: Array<[number, string]>;
Describes the different shape options available for individual pixels.
const pixelShape: QrPixelShapeConfig = {
type: "RoundCorners",
sizeRatio: 1,
cornerRadius: 0.5,
};
-
type
type: "Square" | "Circle" | "Star" | "Rhombus" | "Hexagon" | "Octagon" | "RoundCorners" | "StickyCorners" | "RoundCornersVertical" | "RoundCornersHorizontal";
-
sizeRatio
sizeRatio: number; // Between 0 and 1
-
cornerRadius
cornerRadius: number; // Between 0 and 1, only for "corner" shapes
const data: QrDataConfig = {
type: "Url",
data: { url: "https://example.com" },
};
const options: QrOptionsConfig = {
sizeRatio: 1,
errorCorrectionLevel: "MEDIUM",
};
const data: QrDataConfig = {
type: "Text",
data: { value: "Custom QR Code" },
};
const options: QrOptionsConfig = {
sizeRatio: 0.9,
errorCorrectionLevel: "HIGH",
shapes: {
qrCode: {
type: "Square",
},
matrixPixel: {
pixelShape: { type: "Hexagon", sizeRatio: 0.9 },
color: {
type: "LinearGradient",
colors: [
[0, "#ff0000"],
[1, "#0000ff"],
],
orientation: "Vertical",
},
},
eye: {
type: "Circle",
color: {
type: "LinearGradient",
colors: [
[0, "#ff0000"],
[1, "#0000ff"],
],
orientation: "Vertical",
},
},
eyeFrame: {
type: "Square",
pixelShape: { type: "StickyCorners", cornerRadius: 0.2 },
color: { type: "Solid", value: "#000000" },
},
background: {
color: { type: "Solid", value: "#ffffff" },
},
},
};
const data: QrDataConfig = {
type: "Url",
data: { url: "https://github.com" },
};
const options: QrOptionsConfig = {
sizeRatio: 1,
errorCorrectionLevel: "LOW",
shapes: {
qrCode: {
type: "Circle",
},
matrixPixel: {
pixelShape: {
type: "StickyCorners",
cornerRadius: 0.5,
},
},
logo: {
type: "Circle",
image:
"https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png",
sizeRatio: 0.4,
padding: 1,
color: { type: "Solid", value: "white" },
},
},
};
Ensure that the QR code has sufficient contrast between the foreground and background colors. Avoid using too many colors or complex gradients that may hinder QR code scanners. Also, ensure the error correction level is set appropriately.
Set the errorCorrectionLevel
in QrOptions
to a higher value like 'HIGH'
to improve the QR code's resilience to damage or distortion.
Yes, you can customize pixel shapes using the QrPixelShapeConfig
in shapes.matrixPixel.pixelShape
.
Contributions are welcome! Here are some ideas to improve the library:
- Add new shapes for the eye frame (e.g., multiple ways with rounded corners).
- Implement random color options.
- Add support for more data types.
- Improve documentation and examples.
Released under the MIT License.