> ## Documentation Index
> Fetch the complete documentation index at: https://laravel-qrcode.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Upgrade Guide: Laravel QR Code v1.x to v3.x Migration

> Complete upgrade instructions for moving from linkxtr/laravel-qrcode v1.x to v3.x, including breaking changes, required code updates, and rollback steps.

Version 3.x is a significant release that upgrades the underlying `bacon/bacon-qr-code` library from v2 to v3, hardens the API with strict types, and drops legacy compatibility layers. Most applications need only a few targeted changes to upgrade cleanly.

<Note>
  **Laravel 10 users:** v3.x requires Laravel 12+ and PHP 8.2+. If you are on
  Laravel 10 or PHP 8.1, stay on v1.x — it receives maintenance fixes and is the
  supported path for those environments.
</Note>

## System Requirements

| Requirement | v1.x     | v2.x     | v3.x                   |
| ----------- | -------- | -------- | ---------------------- |
| PHP         | 8.1+     | 8.2+     | **8.2+**               |
| Laravel     | 10+      | 11+      | **12+**                |
| ext-gd      | Required | Optional | Optional               |
| ext-imagick | Optional | Optional | Optional (recommended) |
| Composer    | 2.x      | 2.x      | 2.x                    |

## Breaking Changes

Review every item below before running the upgrade command. Most changes affect only a small number of call sites.

<Accordion title="1. PHP and Laravel version requirements raised">
  The minimum PHP version is now **8.2** and the minimum Laravel version is **12.0**, matching the requirements of `bacon/bacon-qr-code` v3.

  If your `composer.json` pins PHP or Laravel to an older constraint, update it first:

  ```json theme={null}
  "require": {
      "php": "^8.2",
      "laravel/framework": "^12.0"
  }
  ```
</Accordion>

<Accordion title="2. Direct use of upstream library classes (advanced)">
  This item only applies if your application imports classes from the `BaconQrCode` library directly — for example, in a custom renderer or a low-level integration. If you only use the `QrCode` facade, the Blade component, or constructor injection, you are **not affected** and can skip this item.

  The underlying `bacon/bacon-qr-code` library reorganized several namespaces between its v2 and v3 releases. Notable changes include:

  | Old class                                 | New class                                                                                                 |
  | ----------------------------------------- | --------------------------------------------------------------------------------------------------------- |
  | `BaconQrCode\Writer`                      | `BaconQrCode\Writer\Writer`                                                                               |
  | `BaconQrCode\Common\ErrorCorrectionLevel` | Constants updated — see the [bacon/bacon-qr-code releases](https://github.com/Bacon/BaconQrCode/releases) |
</Accordion>

<Accordion title="3. color() and backgroundColor() now require integers">
  Both methods now enforce **integer** arguments (0–255 for RGB, 0–100 for CMYK and alpha). Passing strings throws a type error.

  ```php theme={null}
  // ❌ v1.x — strings were silently accepted
  QrCode::color('255', '0', '0');

  // ✅ v3.x — integers required
  QrCode::color(255, 0, 0);
  ```

  Search your codebase for calls to `->color(` and `->backgroundColor(` and confirm all arguments are integer literals or variables typed as `int`.
</Accordion>

<Accordion title="4. simplesoftwareio/simple-qrcode compatibility dropped">
  v3.x removed the compatibility layer that allowed the `QrCode` facade to act as a drop-in replacement for `simplesoftwareio/simple-qrcode`. If you migrated from that package and relied on any method signatures that do not exist in `linkxtr/laravel-qrcode`'s own API, you will need to update those call sites to use the new API.

  Check the [API reference in the README](https://github.com/Linkxtr/laravel-qrcode/blob/main/README.md#-api-reference) for the current method signatures.
</Accordion>

<Accordion title="5. Strict data validation — InvalidArgumentException on bad input">
  In v1.x, passing malformed data to type methods (such as a bad phone number or an incomplete WiFi config) could silently generate a corrupted QR code. In v3.x, all data types validate their inputs strictly and throw `InvalidArgumentException` on failure.

  Wrap any call that accepts dynamic user input in a `try/catch`:

  ```php theme={null}
  use Linkxtr\QrCode\Contracts\QrCodeExceptionInterface;

  try {
      $qr = QrCode::WiFi([
          'ssid'       => $request->ssid,
          'encryption' => $request->encryption,
          'password'   => $request->password,
      ]);
  } catch (QrCodeExceptionInterface $e) {
      // Return validation error to the user
      return back()->withErrors(['wifi' => $e->getMessage()]);
  }
  ```
</Accordion>

<Accordion title="6. Config defaults changed in v2.4.x">
  Starting in v2.4.0, the package ships with updated defaults to better reflect modern usage:

  | Key                | v1.x / pre-2.4 default | v2.4.x+ / v3.x+ default |
  | ------------------ | ---------------------- | ----------------------- |
  | `format`           | `png`                  | `svg`                   |
  | `size`             | `200`                  | `400`                   |
  | `error_correction` | `H`                    | `M`                     |

  If your application relied on the previous defaults and you have not published the config file, you may notice changes in QR code output after upgrading. Publish the config and set these values explicitly to lock in your preferred defaults.
</Accordion>

## Upgrade Steps

<Steps>
  <Step title="Update the package constraint">
    Run the following command in your project root:

    ```bash theme={null}
    composer require linkxtr/laravel-qrcode:^3.0
    ```

    Composer will pull in the latest v3.x release along with `bacon/bacon-qr-code` v3.
  </Step>

  <Step title="Update color() and backgroundColor() calls">
    Find every call to `->color(` and `->backgroundColor(` in your application and confirm each argument is an integer:

    ```php theme={null}
    // Before
    QrCode::color('255', '0', '0')->generate('Hello');

    // After
    QrCode::color(255, 0, 0)->generate('Hello');
    ```

    A quick search command to locate these calls:

    ```bash theme={null}
    grep -rn "->color\|->backgroundColor" app/ resources/
    ```
  </Step>

  <Step title="Publish and review the config file">
    If you have not already published the config, do so now:

    ```bash theme={null}
    php artisan vendor:publish --tag=qrcode-config
    ```

    This creates `config/qrcode.php`. Open it and explicitly set `format`, `size`, and `error_correction` to match what your application expects, so you are never affected by future default changes:

    ```php theme={null}
    return [
        'format'           => 'svg',  // svg | png | eps | webp
        'size'             => 400,
        'margin'           => 4,
        'error_correction' => 'M',    // L | M | Q | H
        'encoding'         => 'UTF-8',
        'color'            => [0, 0, 0],
        'background_color' => [255, 255, 255],
    ];
    ```
  </Step>

  <Step title="Wrap dynamic inputs in try/catch">
    Identify every place where user-supplied data flows into a data-type method (`WiFi`, `Email`, `PhoneNumber`, `SMS`, `VCard`, etc.) and add `InvalidArgumentException` handling:

    ```php theme={null}
    use InvalidArgumentException;
    use Linkxtr\QrCode\Facades\QrCode;

    try {
        $qr = QrCode::PhoneNumber($request->input('phone'));
    } catch (InvalidArgumentException $e) {
        return response()->json(['error' => $e->getMessage()], 422);
    }
    ```
  </Step>

  <Step title="Clear cached config and views">
    ```bash theme={null}
    php artisan config:clear
    php artisan view:clear
    ```
  </Step>
</Steps>

## Rollback Instructions

If you need to revert to v1.x, run:

```bash theme={null}
composer require linkxtr/laravel-qrcode:^1.0
```

Then clear the cache again:

```bash theme={null}
php artisan config:clear
php artisan view:clear
```

<Warning>
  If you published `config/qrcode.php` during the v3.x migration and changed
  values, review the config after rolling back — the v1.x config schema may
  differ from v3.x.
</Warning>
