Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Bacon Qr Code Laravel Package

bacon/bacon-qr-code

BaconQrCode is a pure-PHP QR code generator ported from ZXing's encoder. It renders QR codes to PNG, SVG, EPS or GD images with customizable size, margin, colors, gradients and eye styles, backed by a fast Reed-Solomon codec for quick output. Encoder only.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with Composer: composer require bacon/bacon-qr-code. There is no Laravel service provider; it is a framework-agnostic PHP library you wire into your app.
  • First decide on a backend:
    • SvgImageBackEnd — best default for web, email, PDFs, and artifact-free output. Requires ext-xmlwriter.
    • GDLibRenderer — simple PNG output using ext-gd; square modules only, no gradients/curves.
    • ImagickImageBackEnd — styled raster output using ext-imagick; supports more visual features but has known rasterizer artifacts.
  • Minimal controller usage with SVG:
use BaconQrCode\Renderer\Image\SvgImageBackEnd;
use BaconQrCode\Renderer\ImageRenderer;
use BaconQrCode\Renderer\RendererStyle\RendererStyle;
use BaconQrCode\Writer;

Route::get('/invites/{invite}/qr', function (Invite $invite) {
    $writer = new Writer(
        new ImageRenderer(new RendererStyle(400), new SvgImageBackEnd())
    );

    $svg = $writer->writeString($invite->signedUrl());

    return response($svg, 200)
        ->header('Content-Type', 'image/svg+xml');
});
  • First real use case: encode a signed URL, ticket reference, invoice payment link, or TOTP provisioning URI into a QR code and render it inline or as a download.
  • Look first at the README’s renderer examples, then Writer, RendererStyle, and the backend classes. The API surface is small: build a renderer, wrap it in Writer, then call writeString() or writeFile().

Implementation Patterns

  • Wrap generation in a small service. Keep renderer construction out of controllers so backend choice, sizing, margins, and colors are consistent:
namespace App\Services;

use BaconQrCode\Renderer\Image\SvgImageBackEnd;
use BaconQrCode\Renderer\ImageRenderer;
use BaconQrCode\Renderer\RendererStyle\RendererStyle;
use BaconQrCode\Writer;

class QrCodeService
{
    public function svg(string $payload, int $size = 400): string
    {
        $writer = new Writer(
            new ImageRenderer(
                new RendererStyle($size, 4),
                new SvgImageBackEnd()
            )
        );

        return $writer->writeString($payload);
    }
}
  • Use SVG inline in Blade or email. For emails, either embed the SVG string directly where supported or base64-encode it as a data URI:
$dataUri = 'data:image/svg+xml;base64,' . base64_encode($qrCodeService->svg($url));
  • Use writeString() for HTTP responses and writeFile() for storage. For downloads:
return response($png, 200, [
    'Content-Type' => 'image/png',
    'Content-Disposition' => 'attachment; filename="ticket.png"',
]);

For persisted files:

Storage::disk('public')->put(
    "qr/tickets/{$ticket->id}.svg",
    $qrCodeService->svg($ticket->verificationUrl())
);

Ensure the parent directory exists before calling writeFile() if you use that method directly.

  • Choose backend by environment capability. SVG is the safest default. If you need PNG on shared hosting without Imagick, use GDLibRenderer:
use BaconQrCode\Renderer\GDLibRenderer;
use BaconQrCode\Writer;

$writer = new Writer(new GDLibRenderer(400));
$png = $writer->writeString($payload);

Do not try to use ImageRenderer with GD; GD support is exposed only through GDLibRenderer.

  • Cache generated output by payload and style. QR generation is cheap but not free at scale. Use a hash of payload, size, margin, backend, and style options as the cache key. Cache SVG strings for inline rendering and cached files for downloadable assets.

  • Queue batch generation. For event badges, invoice batches, or ticket exports, generate in a job and write files to Storage. Avoid rendering hundreds of QR codes synchronously in a web request.

  • Keep payloads short and intentional. QR density grows with payload length. Prefer short signed URLs or compact references over large JSON blobs. For payment QR codes, encode the exact payload string required by the payment provider rather than inventing a format.

  • Treat QR contents as public. A QR code is just an encoding of its payload; anyone who sees it can read it. Never put secrets, raw API tokens, or sensitive personal data directly in a QR code. Use signed, short-lived URLs or opaque references.

  • Test generated output structurally. The package is encoder-only, so you cannot decode its own output. Assert that SVG output is valid XML, has expected dimensions/attributes, and that PNG/SVG responses have the correct content type. Use real scanner tests for critical flows.

  • Prefer the latest 3.x release. Recent releases fix SVG gradient ID collisions, locale-sensitive SVG formatting, Kanji encoding, EC block counts, GD memory handling, and EPS arc rendering. If you generate multiple styled SVGs on one page, upgrade to at least 3.1.x.

Gotchas and Tips

  • Imagick can produce white pixel artifacts. The README documents single white pixels inside filled regions, especially with margin 0, caused by an ImageMagick rasterizer bug. The library cannot reliably work around it. Use SvgImageBackEnd or GDLibRenderer for artifact-free output. Do not attempt to post-process by removing isolated white pixels; that can corrupt legitimate curved modules.

  • GD is intentionally limited. GDLibRenderer does not support gradients or curved module shapes, so QR codes are always square. If your design requires gradients, rounded modules, or custom eye styles, use SVG or Imagick.

  • Extension availability causes runtime failures. SvgImageBackEnd needs ext-xmlwriter; GDLibRenderer needs ext-gd; ImagickImageBackEnd needs ext-imagick. Declare the extension you rely on in composer.json platform requirements and verify it in deployment. Add a fallback path if you support multiple hosting environments.

  • Version 3 requires PHP 8.1+. If you maintain an older Laravel/PHP application, you may need the 2.x line. Check the changelog before upgrading across major versions.

  • Non-ASCII payloads need attention. For Unicode content, be explicit about encoding and verify with the actual scanners you support. Version 3 added configurable UTF-8 ECI prefix behavior and fixed Kanji byte handling, so older releases are a poor choice for multilingual QR content.

  • Keep the quiet zone. The default margin exists for a reason. Reducing margin to 0 for design reasons can hurt scan reliability and makes Imagick edge artifacts more visible. Keep at least a few modules of light margin unless you have tested extensively.

  • High contrast and adequate module size matter more than styling. Dark foreground on light background scans best. Transparent backgrounds can look good in a UI but fail on dark surfaces or in print. If you place a logo over the center, test with multiple phone cameras and scanner apps.

  • SVG gradient IDs are now unique, but older versions were not. If you render several gradient QR codes inline on the same page, older versions could reuse IDs and cause one QR code’s gradient to affect another. Upgrade to 3.1.x, which uses xxh3-based IDs.

  • Locale formatting bugs existed in older SVG output. Decimal separators could break SVG transforms under locales that use commas. This was fixed; upgrade rather than patching generated output.

  • Imagick output format is configurable, but response headers are your responsibility. If you generate PNG, JPEG, or another raster format, set the matching Content-Type and file extension. Do not assume writeString() always returns PNG.

  • writeFile() does not replace Laravel storage abstractions. For application files, prefer writeString() plus Storage::put(). That keeps paths, disks, permissions, and test fakes under Laravel’s control.

  • Do not use this package for decoding or validating QR images. It contains the encoder only. If you need to read uploaded QR codes, use a separate decoder or a browser-side scanner library.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package