# Changelog New updates and improvements to Laravel’s open source products. ## July 2025 ## Laravel Framework 12.x ### Added Verbose Output for `queue:work` Pull requests by [@seriquynh](https://github.com/laravel/framework/pull/56086) & [@amirhshokri](https://github.com/laravel/framework/pull/56095) 1php artisan queue:work --verbose 2// App\Jobs\UrgentAction 85 high 3// App\Jobs\NormalAction 84 default php artisan queue:work --verbose // App\Jobs\UrgentAction 85 high // App\Jobs\NormalAction 84 default With `--verbose`, you’ll now see queue names alongside each job and job ID, making multi-queue debugging straightforward and saving you time when tracing issues. ### `Uri` Implements `JsonSerializable` Pull request by [@devajmeireles](https://github.com/laravel/framework/pull/56097) 1echo json_encode(new Uri('/path?x=1')); 2// "http://localhost:8000/path?x=1" echo json_encode(new Uri('/path?x=1')); // "http://localhost:8000/path?x=1" This release fixes a serialization bug, properly converting the URI to a string when serializing a larger JSON object that contains the URI as a value. ### Added `doesntStartWith()` & `doesntEndWith()` `Str` Methods Pull request by [@balboacodes](https://github.com/laravel/framework/pull/56168) 1str('apple')->doesntStartWith('b'); // true 2str('apple')->doesntEndWith('e'); // false str('apple')->doesntStartWith('b'); // true str('apple')->doesntEndWith('e'); // false The inverse of `startsWith`/`endsWith`, these new methods allow you to fluently test for starting and ending characters in your string. ### Closure Support in `pluck()` Pull request by [@ralphjsmit](https://github.com/laravel/framework/pull/56188) 1$users->pluck(fn($u) => $u->email, fn($u) => strtoupper($u->name)); $users->pluck(fn($u) => $u->email, fn($u) => strtoupper($u->name)); You can now dynamically generate keys and values via callbacks. Instead of mapping then plucking, you get a single, flexible method that reduces steps and keeps intent clear. ## Pint ### Added `--parallel` Option Pull request by [@nunomaduro](https://github.com/laravel/pint/pull/376) 1./vendor/bin/pint --parallel ./vendor/bin/pint --parallel By leveraging PHP CS Fixer’s parallel runner, [Pint](https://laravel.com/docs/12.x/pint) now formats files concurrently. On large codebases that once took minutes, you’ll see results in seconds, speeding up both local workflows and CI pipelines for a clear quality of life win. ## Telescope ### Migrated to Vite Pull request by [@nckrtl](https://github.com/laravel/telescope/pull/1598) Telescope’s frontend now uses [Vite](https://laravel.com/docs/12.x/vite) instead of Mix. Asset builds finish faster, hot-reloads are more reliable, and you benefit from a modern toolchain without changing your workflow. ## Octane ### FrankenPHP’s File Watcher Pull request by [@kohenkatz](https://github.com/laravel/octane/pull/971) [Octane](https://laravel.com/docs/12.x/octane) now relies on [FrankenPHP](https://frankenphp.dev)’s native file watcher for reloading the server on file changes. This removes the NodeJS dependency and eases the local development process significantly. ## Inertia ### Reset Form State and Clear Errors with a Single Method Pull request by [@pascalbaljet](https://github.com/inertiajs/inertia/pull/2414) 1const form = useForm({ name: "", email: "" }); 2  3// Instead of: 4form.reset(); 5form.clearErrors(); 6  7// You can now: 8form.resetAndClearErrors(); const form = useForm({ name: "", email: "" }); // Instead of: form.reset(); form.clearErrors(); // You can now: form.resetAndClearErrors(); You can now concisely reset all fields and errors in one go, bringing your form back to square one. ### Prevent Minifying JavaScript Builds and Test Apps Pull request by [@pascalbaljet](https://github.com/inertiajs/inertia/pull/2424) Inertia no longer distributes minified builds, aligning it with the strategy of other popular libraries. This makes debugging more straightforward and allows for local patching if the need arises. ## June 2025 ## Laravel Framework 12.x ### Added `encrypt()` and `decrypt()` String Helper Methods Pull request by [@KIKOmanasijev](https://github.com/laravel/framework/pull/55931) You can now chain `encrypt()` and `decrypt()` directly on a `Str` instance, so instead of piping your string through separate encryption calls, you can write: 1$value = Str::of('secret')->encrypt()->prepend('Encrypted: '); 2$original = Str::of($value)->decrypt(); $value = Str::of('secret')->encrypt()->prepend('Encrypted: '); $original = Str::of($value)->decrypt(); This keeps your string-manipulation chains concise (no need to write separate, extra code to handle encryption) and you don’t have to manually wrap a value in encryption calls each time. Learn more about [`encrypt`](https://laravel.com/docs/12.x/helpers#method- encrypt) and [`decrypt`](https://laravel.com/docs/12.x/helpers#method-decrypt) ### Added `broadcast_if()` and `broadcast_unless()` Utilities Pull request by [@taylorotwell](https://github.com/laravel/framework/pull/55967) You now have two methods for conditional broadcasting in a single call: 1broadcast_if($order->isPaid(), new OrderShipped($order)); 2broadcast_unless($user->isActive(), new InactiveUserAlert($user)); broadcast_if($order->isPaid(), new OrderShipped($order)); broadcast_unless($user->isActive(), new InactiveUserAlert($user)); This replaces multi-line conditionals around `broadcast()` and makes your event logic more readable, improving the overall developer experience. Read the docs about [event broadcasting in Laravel](https://laravel.com/docs/12.x/broadcasting) ### Added `--batched` Flag to `make:job` Pull request by [@hafezdivandari](https://github.com/laravel/framework/pull/55929) The `php artisan make:job` command now accepts a `--batched` option: 1php artisan make:job ProcessPodcast --batched php artisan make:job ProcessPodcast --batched This command scaffolds the job with the `Batchable` trait already applied, so you don’t have to add it manually. It saves you a manual step and ensures consistency. Learn more about [defining batchable jobs](https://laravel.com/docs/12.x/queues#defining-batchable-jobs) ## VS Code Extension ![VS Code Performance Improvements](/images/changelog/2025-06/vs-code- performance-improvements.png) ### Memory Improvements Pull request by [@joetannenbaum](https://github.com/laravel/vs-code- extension/pull/402) We fixed a memory-leak issue in the extension’s background processes, reducing its long-term footprint and preventing slowdowns during extended coding sessions. ### Improved Startup Time Pull request by [@joetannenbaum](https://github.com/laravel/vs-code- extension/pull/404) Initialization with the VS Code extension now completes in under one second (down from 5–7 seconds) by deferring heavy setup until it’s actually needed. You’ll notice the extension loads almost instantly so you can start building faster. Get started with the [Laravel VS Code extension](https://github.com/laravel/vs-code-extension) ## Inertia ### Allow `deepMerge` on Custom Properties Pull request by [@mpociot](https://github.com/inertiajs/inertia/pull/2344) When implementing infinite scrolling with Inertia or other paginated data merges, you can now specify a key (`matchOn`) to do a deep merge, matching items by ID and replacing or appending as appropriate. This provides greater flexibility, prevents duplicated entries, and keeps your client-side data consistent. 1Inertia::render('Users/Index', [ 2 'users' => Inertia::deepMerge($users)->matchOn('data.id'), 3]); Inertia::render('Users/Index', [ 'users' => Inertia::deepMerge($users)->matchOn('data.id'), ]); [Learn more in the Inertia docs](https://inertiajs.com/merging-props#server- side) ### Prevent Duplicate Render in React Pull request by [@pascalbaljet](https://github.com/inertiajs/inertia/pull/2377) We fixed a React-specific issue in `` where the initial Inertia page would render twice. Now you get a single, clean first render without flicker, improving perceived performance. Get started with the [Laravel + React Starter Kit](https://www.youtube.com/watch?v=_sw61Ew1FHQ)