jamal / laravel-qrcode
Dependency-free Laravel QR Code generator with pure-PHP SVG renderer and optional GD/Imagick PNG.
v1.0.5
2026-06-26 16:35 UTC
Requires
- php: ^8.2
- illuminate/support: ^10.0|^11.0|^12.0
- illuminate/view: ^10.0|^11.0|^12.0
README
A dependency-free Laravel QR Code generator with a pure-PHP SVG renderer and optional PNG via GD/Imagick.
Standards Compliance
- Implements ISO/IEC 18004 for Versions 1–40 (auto-selected from the data length).
- Modes: Numeric, Alphanumeric, Byte (UTF-8).
- Error correction: L, M, Q, H via Reed–Solomon over GF(256).
- Masking: evaluates masks 0–7 and selects the lowest-penalty matrix.
- Full function patterns: finder, separators, timing, alignment (v2+), dark module, 15-bit format information (both copies), and 18-bit version information (v7+).
- Output is byte-identical to reference encoders and decodes on standard readers (verified with ZBar across modes, ECC levels, and versions 1–13+).
- Quiet zone default is 4 modules (configurable via
margin).
Installation
composer require jamal/laravel-qrcode
php artisan vendor:publish --tag=config --provider="Jamal\QrCode\QrCodeServiceProvider"
Quick Start
use QrCode; echo QrCode::text('Hello World')->renderer('svg')->toSvg();
Examples
1) SVG and PNG
QrCode::text('Hello')->toSvg(); QrCode::text('Hello')->renderer('gd')->toPng();
2) Save to file
QrCode::text('Save')->renderer('svg')->save(storage_path('app/qr.svg')); QrCode::text('Save')->renderer('gd')->save(storage_path('app/qr.png'));
3) Controller Response
return QrCode::text('Hello')->toSvgResponse(); // or return QrCode::text('Hello')->renderer('gd')->toPngResponse();
4) Data URI
$uri = QrCode::text('Embed')->toDataUri('svg'); // or 'png'
5) Blade directive
@qrcode('https://example.com', ['ecc' => 'Q', 'size' => 256, 'renderer' => 'svg'])
6) ECC Level, Version, Colors, Transparent BG
QrCode::text('Critical')->ecc('H')->version(2)->foreground('#111111')->background('#ffffff')->toSvg(); QrCode::text('Transparent')->background('transparent')->toSvg();
7) Wi-Fi, vCard, Alphanumeric
QrCode::text('WIFI:S:Home;T:WPA;P:secret;;')->toSvg(); $vcard = "BEGIN:VCARD\nVERSION:3.0\nFN:John Doe\nTEL:+123456789\nEMAIL:john@example.com\nEND:VCARD"; QrCode::text($vcard)->toSvg(); QrCode::text('ABCD-1234 $%*+-./:')->toSvg(); // Alphanumeric mode
8) Artisan
php artisan qrcode:make "Hello" --path=storage/app/hello.png --ecc=Q --version=2 --renderer=svg --size=256 --margin=4 --fg=#000000 --bg=#ffffff
Configuration (config/qrcode.php)
return [ 'version' => null, // auto 'ecc' => 'M', 'margin' => 4, 'scale' => 10, 'renderer' => 'svg', // svg|gd|imagick 'fg_color' => '#000000', 'bg_color' => '#ffffff', 'eci' => false, 'cache' => false, 'cache_ttl' => 3600, ];
Troubleshooting: "the QR code won't scan"
The encoder output is standards-compliant, so a code that fails to scan is almost always a rendering or display problem. Check the following:
- Do not stretch the image. Keep the QR perfectly square. When embedding the SVG,
never force a non-square
width/heightin CSS. The SVG usespreserveAspectRatio='xMidYMid meet'so it letterboxes instead of distorting, but a container withobject-fitoverrides or fixed mismatched dimensions can still squash it. - Keep the quiet zone. Leave the default
marginof 4 modules. Don't crop the white border or place the code tight against other dark content. - Render big enough. Aim for at least ~3–4 device pixels per module. For higher
versions (longer data) increase
scaleor reduce the data length. - Preserve contrast. Dark foreground on a light background. Avoid low-contrast color pairs and never invert (light modules on dark background won't scan on most readers).
- Avoid post-processing. Anti-aliasing, JPEG compression of small images, or scaling to non-integer multiples blurs module edges. Prefer SVG, or PNG scaled by whole numbers.
- Shorten the payload. Very long URLs push the symbol to a high version with tiny
modules. Use a redirect/short link, or raise
scale.
Security & Performance
- Validate and limit input length to prevent excessive memory usage.
- Use SVG when possible for crisp scaling. GD/Imagick are optional for PNG.
- Avoid untrusted content injection when echoing inline HTML; prefer Response helpers.
License
MIT