Laravel 13: Features, Helpers &amp; Upgrade Notes | Mohamed Said        [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com) [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles  ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

       [  ](https://github.com/EG-Mohamed)       

 [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

  [ home ](https://msaied.com)    [ articles ](https://msaied.com/articles)    Laravel 13: New Features, Helpers, and Practical Upgrade Notes        On this page       1. [  What Laravel 13 Actually Changes ](#what-laravel-13-actually-changes)
2. [  Bootstrapping and Application Lifecycle ](#bootstrapping-and-application-lifecycle)
3. [  New Helpers Worth Knowing ](#new-helpers-worth-knowing)
4. [  rescue\_unless ](#coderescue-unlesscode)
5. [  str()-&gt;toBase64url() and fromBase64url() ](#codestr-gttobase64urlcode-and-codefrombase64urlcode)
6. [  Collection::groupByMany() ](#codecollectiongroupbymanycode)
7. [  PHP 8.3 Integrations ](#php-83-integrations)
8. [  Breaking Changes to Watch ](#breaking-changes-to-watch)
9. [  Illuminate\\Http\\Client\\Response::json() strict mode ](#codeilluminatehttpclientresponsejsoncode-strict-mode)
10. [  Removed: $loop variable in Blade @each ](#removed-codeloopcode-variable-in-blade-code-at-eachcode)
11. [  Queue after\_commit default ](#queue-codeafter-commitcode-default)
12. [  Upgrade Checklist ](#upgrade-checklist)
13. [  Key Takeaways ](#key-takeaways)

  ![Laravel 13: New Features, Helpers, and Practical Upgrade Notes](https://cdn.msaied.com/404/bdf42eb6d0b2dba65e7248a284b40cf2.png)

  #laravel   #laravel-13   #php   #upgrade  

 Laravel 13: New Features, Helpers, and Practical Upgrade Notes 
================================================================

     9 Jul 2026      4 min read    ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said  

       Table of contents

  13 sections  

1. [  01   What Laravel 13 Actually Changes  ](#what-laravel-13-actually-changes)
2. [  02   Bootstrapping and Application Lifecycle  ](#bootstrapping-and-application-lifecycle)
3. [  03   New Helpers Worth Knowing  ](#new-helpers-worth-knowing)
4. [  04   rescue\_unless  ](#coderescue-unlesscode)
5. [  05   str()-&gt;toBase64url() and fromBase64url()  ](#codestr-gttobase64urlcode-and-codefrombase64urlcode)
6. [  06   Collection::groupByMany()  ](#codecollectiongroupbymanycode)
7. [  07   PHP 8.3 Integrations  ](#php-83-integrations)
8. [  08   Breaking Changes to Watch  ](#breaking-changes-to-watch)
9. [  09   Illuminate\\Http\\Client\\Response::json() strict mode  ](#codeilluminatehttpclientresponsejsoncode-strict-mode)
10. [  10   Removed: $loop variable in Blade @each  ](#removed-codeloopcode-variable-in-blade-code-at-eachcode)
11. [  11   Queue after\_commit default  ](#queue-codeafter-commitcode-default)
12. [  12   Upgrade Checklist  ](#upgrade-checklist)
13. [  13   Key Takeaways  ](#key-takeaways)

       What Laravel 13 Actually Changes
--------------------------------

Laravel 13 is a focused release. Rather than a sweeping API redesign, it tightens the framework's internals, promotes PHP 8.3 features to first-class status, and ships a handful of helpers that remove common boilerplate. The upgrade path from Laravel 12 is intentionally narrow — most apps need only a few targeted changes.

---

Bootstrapping and Application Lifecycle
---------------------------------------

The `Application` bootstrap sequence now exposes a dedicated `booting` / `booted` hook pair directly on the application instance, giving you a cleaner place to register deferred work without abusing service providers.

```php
// bootstrap/app.php
return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(web: __DIR__.'/../routes/web.php')
    ->booting(function (Application $app) {
        // Runs before any provider boot() is called.
        $app->bind(ReportFormatter::class, JsonReportFormatter::class);
    })
    ->booted(function (Application $app) {
        // All providers are booted; safe to resolve.
        $app->make(MetricsCollector::class)->register();
    })
    ->create();

```

This replaces the pattern of creating a throwaway service provider just to hook into the lifecycle.

---

New Helpers Worth Knowing
-------------------------

### `rescue_unless`

The inverse of `rescue()`. It runs the callback only when the condition is falsy, swallowing exceptions and returning a default — useful for optional third-party calls:

```php
$price = rescue_unless(
    condition: $this->cache->has('price:'.$sku),
    callback: fn () => $this->pricingApi->fetch($sku),
    rescue: null
);

```

### `str()->toBase64url()` and `fromBase64url()`

URL-safe Base64 encoding lands on the `Stringable` fluent API, removing the need for manual `strtr` gymnastics:

```php
$token = str($payload)->toBase64url();
$decoded = str($token)->fromBase64url();

```

### `Collection::groupByMany()`

Groups a collection by multiple keys in a single pass, returning a nested structure:

```php
$grouped = $orders->groupByMany(['region', 'status']);
// $grouped['EU']['pending'] => Collection of orders

```

---

PHP 8.3 Integrations
--------------------

Laravel 13 requires PHP 8.2 minimum and is optimised for 8.3. Typed class constants are now used throughout the framework's own codebase, and the `json_validate()` built-in replaces several internal `json_decode` + error-check patterns. Your own code can follow the same idiom:

```php
// Before
$valid = json_decode($raw, true) !== null && json_last_error() === JSON_ERROR_NONE;

// After (PHP 8.3)
$valid = json_validate($raw);

```

Readonly class promotion is also used in new stubs, so generated DTOs and form requests lean on `readonly` properties by default.

---

Breaking Changes to Watch
-------------------------

### `Illuminate\Http\Client\Response::json()` strict mode

Passing an invalid JSON body no longer silently returns `null`; it throws `JsonException`. Wrap legacy HTTP client calls:

```php
try {
    $data = Http::get($url)->json();
} catch (\JsonException $e) {
    Log::warning('Malformed API response', ['url' => $url]);
    $data = [];
}

```

### Removed: `$loop` variable in Blade `@each`

The `$loop` magic variable inside `@each` directives was deprecated in Laravel 12 and is removed in 13. Replace `@each` with `@foreach` to retain loop metadata.

### Queue `after_commit` default

The `after_commit` flag on dispatched jobs now defaults to `true` when a database transaction is active. If you rely on jobs firing mid-transaction for testing or side-effects, set `public bool $afterCommit = false` explicitly on the job class.

---

Upgrade Checklist
-----------------

- Run `composer require laravel/framework:^13.0` and fix any immediate constraint failures.
- Search for `@each` in Blade templates and convert to `@foreach`.
- Audit HTTP client calls that parse JSON — add `JsonException` handling.
- Review jobs that dispatch inside transactions; verify `$afterCommit` intent.
- Update `phpunit.xml` to the Laravel 13 stub if you are on PHPUnit 11.
- Run `php artisan config:clear && php artisan cache:clear` after deployment.

---

Key Takeaways
-------------

- The new `booting` / `booted` hooks on `Application` reduce throwaway service providers.
- `rescue_unless`, `toBase64url`, and `groupByMany` cover real day-to-day gaps.
- `Http::json()` now throws on bad JSON — handle it explicitly.
- `@each` is gone; `after_commit` defaults changed for queued jobs.
- PHP 8.3 is the sweet spot; `json_validate()` and readonly properties are first-class.

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fmsaied.com%2Farticles%2Flaravel-13-new-features-helpers-and-practical-upgrade-notes-1&text=Laravel+13%3A+New+Features%2C+Helpers%2C+and+Practical+Upgrade+Notes) [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fmsaied.com%2Farticles%2Flaravel-13-new-features-helpers-and-practical-upgrade-notes-1) 

 Frequently Asked Questions 
----------------------------

  3 questions  

     Q01  Is the upgrade from Laravel 12 to 13 disruptive?        For most apps, no. The main breaking changes are the Http client throwing JsonException on bad JSON, the removal of $loop inside @each, and the changed after_commit default for jobs. A focused audit of those three areas covers the majority of upgrade work. 

      Q02  Does Laravel 13 require PHP 8.3?        No — the minimum is PHP 8.2. However, the framework is optimised for 8.3 and uses features like json_validate() and typed class constants internally. Running 8.3 gives you the best performance and the cleanest code alignment with the new stubs. 

      Q03  What replaces the @each directive now that it is removed?        Use a standard @foreach loop. The @each directive was a convenience wrapper that never supported the full $loop variable reliably. Switching to @foreach gives you $loop, better IDE support, and clearer template logic. 

  Continue reading

 More Articles 
---------------

 [ View all    ](https://msaied.com/articles) 

 [ ![Laravel New in 12: First-Class Typed Config, Slim Skeletons, and Upgrade Notes](https://cdn.msaied.com/401/bd0219f2cb584b037df76f985db348f8.png) laravel laravel-12 php 

### Laravel New in 12: First-Class Typed Config, Slim Skeletons, and Upgrade Notes

Laravel 12 ships with typed configuration objects, a leaner application skeleton, and several quality-of-life...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 9 Jul 2026     3 min read  

  Read    

 ](https://msaied.com/articles/laravel-new-in-12-first-class-typed-config-slim-skeletons-and-upgrade-notes) [ ![Laravel API Resources: Sparse Fieldsets, Conditional Relationships, and Versioning](https://cdn.msaied.com/400/67fe9d3c6c505a6f67092e2761690696.png) laravel api resources 

### Laravel API Resources: Sparse Fieldsets, Conditional Relationships, and Versioning

Go beyond basic transformers. Learn how to implement sparse fieldsets, conditionally load relationships, and v...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 9 Jul 2026     3 min read  

  Read    

 ](https://msaied.com/articles/laravel-api-resources-sparse-fieldsets-conditional-relationships-and-versioning-1) [ ![Laravel Eloquent Global Scopes: Bootable Traits, Scope Removal, and Testing Pitfalls](https://cdn.msaied.com/399/71a080bda5c9aa713a95cec2c8b42247.png) laravel eloquent testing 

### Laravel Eloquent Global Scopes: Bootable Traits, Scope Removal, and Testing Pitfalls

Global scopes silently shape every query on a model. Learn how to write bootable trait scopes, safely remove t...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 9 Jul 2026     3 min read  

  Read    

 ](https://msaied.com/articles/laravel-eloquent-global-scopes-bootable-traits-scope-removal-and-testing-pitfalls) 

   [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

Explore

- [Home](https://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [Contact](https://msaied.com#contact-section)

Connect

- [   hello@msaied.com ](mailto:hello@msaied.com)
- [   +20 109 461 9204 ](tel:+201094619204)

© 2026 Mohamed Said. All rights reserved.

 [  ](https://github.com/EG-Mohamed) [  ](https://www.linkedin.com/in/msaiedm/) [  ](https://wa.me/201094619204) [  ](mailto:hello@msaied.com) [  ](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
