r/laravel

What do you check before installing a Laravel package? Here's my checklist.
▲ 24 r/laravel

What do you check before installing a Laravel package? Here's my checklist.

I've been using Laravel since the 5.x days, and one thing I've learned after maintaining and upgrading applications across multiple framework versions is this:

Choosing the right package is often more important than writing the code itself.

Every composer require is a long-term commitment. The package you install today can affect future upgrades, security, debugging, onboarding, and the overall maintainability of your application.

Over the years, I've developed a checklist that I go through before adding any third-party package. It has helped me avoid abandoned packages, unnecessary dependencies, and maintenance headaches.

https://sagautam5.medium.com/12-things-i-check-before-installing-any-laravel-package-10d51fc1dc26

I'd love to hear what everyone else looks for before installing a package.

Do you look at:

  • Maintainer activity?
  • Test coverage?
  • Release frequency?
  • Number of dependencies?
  • Something else that I've missed?
u/sagautam5 — 1 day ago
▲ 10 r/laravel

Lens for Laravel v3.0 is out: WCAG 2.0/2.1/2.2 scans, interactive states, and a more reliable AI Fix

Hey everyone!

Lens for Laravel has now passed 2,500 downloads, and version 3.0 is available.

Lens is an open-source accessibility auditing package for Laravel. It runs axe-core in Chromium and maps detected issues back to the relevant Blade, React, or Vue source files instead of only showing a CSS selector.

The main additions in v3.0 are:

  • WCAG 2.0, 2.1, and 2.2 selection in both the dashboard and CLI
  • interactive state scanning for menus, modals, tabs, and other dynamic UI
  • URL- and state-aware scan history comparisons
  • a more reliable AI Fix workflow with smaller, focused code changes, controlled retries, and clearer errors
  • immediate “pending re-scan” status after applying an AI fix
  • consistent local HTTPS support for scans, crawling, and previews
  • complete English, Polish, Spanish, French, and German translations
  • Laravel 13 support

AI Fix can use your configured OpenAI, Anthropic, or Gemini provider through Laravel AI. It remains completely optional - all scanning, history, crawling, reports, previews, and CLI features work without it.

I’ve attached a short demo video showing an accessibility issue being corrected with AI Fix.

Website and documentation:
https://lens.webcrafts.pl/

GitHub:
https://github.com/webcrafts-studio/lens-for-laravel

Feedback is very welcome - especially if you try it in a real Laravel project.

Building a Hook System Like WordPress in Laravel with Mksine

One thing I’ve always missed in Laravel applications is a simple way for packages and modules to modify behavior without tightly coupling everything together.

WordPress solved this years ago with Actions and Filters.

So while working on my Laravel + Filament project (Mksine), I decided to implement a hook system inspired by WordPress.

The Problem

As projects grow, adding extension points becomes difficult.

For example:

  • A plugin wants to add a menu item.
  • A theme wants to modify page output.
  • A package wants to inject content into a dashboard widget.
  • Another module wants to change data before it’s saved.

Without a hook system, this usually ends up as:

  • Event listeners everywhere
  • Service container hacks
  • Hardcoded integrations
  • Direct dependencies between modules

The Approach

I built a lightweight hook manager that supports:

Actions

Execute code at specific points in the application lifecycle.

Hook::addAction('dashboard.render', function () {
// Custom logic
});

Hook::doAction('dashboard.render');

Filters

Modify values before they are returned.

Hook::addFilter('page.title', function ($title) {
return $title . ' - Powered by Mksine';
});

$title = Hook::applyFilters('page.title', $title);

Priorities

Multiple hooks can run in a predictable order.

Hook::addAction('menu.register', $callback, 10);

Why Not Just Use Laravel Events?

Laravel events are great.

But events are primarily designed for application workflows.

Hooks provide a more flexible extension layer where plugins and themes can modify behavior without needing explicit knowledge of each other.

For CMS-like systems, this becomes incredibly useful.

What This Enables

With hooks, Mksine can support:

  • Plugins
  • Themes
  • Dynamic menus
  • Dashboard extensions
  • Page builder integrations
  • Media integrations
  • Third-party modules

without requiring core modifications.

I’m Curious

Have you implemented a hook/filter system in Laravel before?

If so:

  • Did you use Events?
  • Custom middleware?
  • Something else?

I’d love to hear how others approached extensibility in Laravel applications.

GitHub: https://github.com/MiranSalehi/mksine

u/Top_Knowledge_1519 — 2 days ago
▲ 93 r/laravel

Laravel jobs are nowhere to be found

It’s a bad economy, I give you that but unlike spring boot of JAVA and some other languages, PHP/Laravel jobs seem to be nowhere to be found. Laravel as a framework is great but at the end of the day, it should be translated to an income.

Before you start posting a job board that’s dedicated for Laravel alone, do a comparison to other languages/frameworks in the other jobs boards.

reddit.com
u/madeininternet666 — 4 days ago
▲ 10 r/laravel+1 crossposts

LLM Provider Fallback in PHP: Automatic Failover in Neuron AI Router

I just released an update to the Router component of Neuron AI. For anyone who hasn't come across it, Neuron is the agentic framework of the PHP ecosystem. It allows you to develop agentic applications, from simple agent with tool calls to complex agentic workflow in pure PHP.

The router component allows you to define a fallback order of providers and if one fails with a transient error, the next is tried transparently. On top of that, you can add routing rules to choose which provider handles each request.

Neuron Router Release: https://inspector.dev/llm-provider-fallback-in-php-automatic-failover-in-neuron-ai-router/

Repository: https://github.com/neuron-core/router

Docs: https://docs.neuron-ai.dev

u/valerione — 3 days ago
▲ 96 r/laravel+1 crossposts

You probably don't need a database per tenant. A detailed explainer on multitenancy data isolation across Postgres, MySQL and SQLite

I've been doing Laravel multitenancy for years and kept seeing teams reach straight for a database per tenant, mostly because it's hat most of the popular packages offer by default. So I wrote up the whole spectrum of data isolation approaches. Separate instance, separate database, schemas/prefixes, partitioning, and discriminator column, along with how each behaves across PostgreSQL, MySQL/MariaDB and SQLite, and where row-level security changes the picture.

The short version: for most apps a discriminator column with RLS on PostgreSQL gets you real, database-enforced isolation at the lowest operational cost, and database-per-tenant is the most expensive answer to a question most apps can answer cheaply.

As with everything when it comes to development, the answer is often "it depends", so I'd love to hear from anyone about their experiences with this, whether good or bad.

ollieread.com
u/ollieread — 5 days ago
▲ 24 r/laravel+2 crossposts

This Week in PHP Internals | July 1, 2026

Hello world, it's Canada Day 2026, and here's what happened This Week in PHP Internals.

This week's episode is supported by OurCVEs. Hundreds of CVEs ship every week, and almost none of them are about you — until one is. OurCVEs inventories your entire infrastructure and only surfaces the security risks that actually apply to your team. Free for open source at ourcves.com.

This week's top story is still Gina P. Banyard's Deprecations for PHP 8.6 — the once-a-year housekeeping RFC that gathers a stack of unrelated removals under one roof, where each one stands or falls on its own separate vote. With 8.6's first alpha getting built this very week, the clock is loud. But the fight this week wasn't about any single removal — it was about evidence: does every deprecation owe voters an impact analysis? Tim Düsterhus argued no, at least not as an unconditional rule — a deprecation has years of runway, and a survey of existing code can't measure the upside of a cleanup.

Juliette Reinders Folmer had offered to build those impact analyses, and her exchange with Tim turned personal — an accusation of gaslighting, which Tim rejected. But she was far from alone on the substance. Rowan Tommins came to her defense, and he didn't warm up first. Rowan wrote: "I hate this argument." His point: deprecating something is really a proposal to remove it later, so the impact of that removal is exactly what voters deserve to see — and to leave it out to protect your case, he said, would be dishonest. Larry Garfield backed the same call: put the impact on the table, or read the angry blog posts come December.

And this particular RFC kept growing right up against the freeze. Seifeddine Gmati proposed deprecating list(), and got the room's attention: Ayesh Karunaratne clocked "7 million hits" for list( on GitHub and called the break too big; Rowan noted you can't really retire list() while array() stays — to which Seif said, fine, then maybe deprecate array() too. Nick moved to reserve namespace as a constant name. Ilia Alshanetsky floated finally sunsetting open_basedir — Derick Rethans said "Yes, but for PHP 9," while Jakub Zelenka was firmly against it. Add a careful fight over how narrowly to kill the dechunk filter, plus Tim's pitch to retire gettype() for get_debug_type(), and that's a lot of small knives being sharpened at once.

Carrying over: Tim and Derick's Time\Duration class — the immutable stopwatch value that's meant to be the first brick of a modern date-and-time API. One line of context, then this week's moves: they're dropping the word "period" from the method names (Derick pointed out ISO itself walked away from it); they're lifting the ban on negative durations after Paweł Kraśnicki showed up with a real use case; and the whole thing may slim down for 8.6 — ship addition, subtraction and multiplication now, and let dividing one duration by another wait. Ignace Nyamagana Butera and Nick are already bikeshedding whether that division should hand you back a tuple or a tidy little value object.

The single busiest thread of the week was brand new: Rob Landers formally opened Primary Constructors — the whole constructor hoisted up onto the class line itself. His numbers are the pitch: something like 30 to 40 percent of all constructors are completely empty, and by his count 71 percent of Laravel and 61 percent of Symfony classes could use this. The catch is deliberate — a class with a primary constructor can't also declare a regular __construct, and it can't carry a body.

That no-body rule is the whole fight. Nick pushed for a body — mostly so readonly classes have a way through — and warned this could ship as yet another half-a-feature. But Rob held the line. He wrote: "If you need a body, use a constructor -- that's what they're for." Rowan and Tim are with Rob — Tim called the limitation "a feature," and put it simply: "[To] reduce typing alone is not a sufficiently strong argument in favor of a new feature." Seifeddine went further: "Personally, I really dislike this feature." His read — primary constructors don't remove repetition, they just relocate it. Larry, meanwhile, wants a Kotlin-style init block bolted on. Plenty's still unresolved — visibility, attributes, anonymous classes — so we'll be keeping an eye on this one.

Newcomer Michal Kral floated a spicy pre-RFC: methods on scalars. Write (3)->pow(2), or " hello "->trim()->upper(), with the call rewritten at compile time into a hidden helper — but only when the compiler can already prove the value is a scalar. He was upfront that he built it with an AI assistant. The reception was cool: Seifeddine's core objection is that PHP compiles one file at a time, so "the compiler already knows it's a scalar" covers almost no real code — the same line would work or fail depending on what's autoloaded. His fix, nicely put: "Solve the naming problem with naming, not by blinding the tooling." And Rob warned the whole thing leans on casts, which in PHP are dangerous(int) of the string "123password" is just 123.

Alex Pătrănescu opened a pre-RFC for runtime modules — a way to give each package its own private symbol table so two versions of the same library can finally coexist in one request. Rowan Tommins spent the week reframing it as containers — a boundary you run other people's code inside, Docker-style — and kept circling the genuinely hard part: what happens when an object crosses the wall between two containers? A second contributor, Alexander Egorov, pitched version "tags" instead; Rowan's worry is that tags leak the container's insides right back out. No code yet — but a problem the whole ecosystem feels.

The rawest thread of the week came from a user, not an internals regular. Michael Morris wrote what he openly called a "Disheartening Rant" after Edmond Dantes said his own TrueAsync RFC has, in his words, a 90 percent chance of not being accepted. Morris didn't hold back: "If you want PHP to be the next COBOL, this is how you go about it." His killer example is WebSockets — the thing PHP still can't really do on its own. Ilia Alshanetsky pushed back gently (he's actually written COBOL, and reports it isn't dead): async matters, but its reach in a request-based language is narrower than it looks.

Larry Garfield drew the line that matters — the same one that just sank generics. Larry wrote: "Don't confuse 'this is not the async we're looking for, done in a painful process' with 'we don't want async at all, ever.' The first is what happened. The second is simply untrue." His critique isn't of async — it's of how TrueAsync arrived: enormous, one author, hundreds of far-reaching decisions, feedback taken selectively. His fix is a real working group to design it together. Nobody's against the destination — they're against the map.

To the ballots — and this was a brutal fortnight for the marquee names. Seifeddine's Bound-Erased Generics closed and was declined: 7 in favour, 19 against, 10 abstaining — nowhere near the two-thirds. And Nicolas Grekas's __exists() magic method went down with it, 2 to 13. The two features that would've made the headlines both missed.

But look what did pass — the quiet, careful stuff, every one without a single No. Tim's deprecation of returning values from __construct and __destruct: accepted unanimously, 39 to nothing. Sjoerd Langkemper's cap on php://filter chains — that local-file-inclusion-to-RCE fix — accepted 30 to nothing, 2 abstaining. And Weilin Du's Locale display-keyword additions: in, 18 to nothing, 2 abstaining. And one's still live on the board — Jordi Kroon's move to lift third-party extension docs out of the manual is out in front at 25 to 1, one abstaining, with the vote closing July 3; on the side questions the room is leaning toward a php.net subpath over a separate subdomain, 14 to 8, and toward dropping the old user notes rather than migrating them, 20 to 4. The pattern's getting hard to miss: the bold swings keep getting sent back, while the tidy, well-scoped changes keep sailing home.

Quick hits. That newcomer arc — Sepehr Mahmoudi's grapheme_mask — got RFC karma and a warm discussion, then tried to call a vote for July 3 and was told, kindly, it's not ready: no discussion link, freeze period not met, window too short — the process catching a first-timer before the fall. Khaled Alam's write-to-constants RFC grew to cover class constants, so its vote slipped. Gianfrancesco Aurecchia's DTLS idea converged fast — Jakub steered it from a new class to a simple dtls:// stream, maybe no RFC needed at all. Gina volunteered to review the long-stranded snmp extension work. Seifeddine's Literal Scalar Types reached version 0.3. Jorg Sowa's case-sensitive-PHP revival was withdrawn. And PHP 8.6.0 alpha 1 got built — which is why everyone's sprinting.

So that's the week: a deprecations RFC that turned into a fight about honesty, a stopwatch class quietly going on a diet, a brand-new primary-constructors debate, a heartfelt plea for async — and the two flagship votes falling while the small ones walked right in. Links to every thread are below. We're Artisan Build. See you next week.

youtube.com
u/ProjektGopher — 5 days ago
▲ 10 r/laravel+2 crossposts

I Updated My Database Backup Guide with a Config Generator Tool. Perfect for self hosted Laravel.

I refreshed my most-read article on automated database backups with Docker Compose. The underlying image moved to nfrastack/container-db-backup, so I updated the whole guide with the new multi-job config format. I also built a little JavaScript configurator that generates docker-compose and .env files on the fly. If you run multiple Laravel projects and want scheduled backups without manual copy-paste, this might save you some time.

https://danielpetrica.com/easy-database-backups-with-docker-compose/

u/HolyPad — 4 days ago
▲ 46 r/laravel

VitoDeploy 4.0 is out - a free, self-hosted server & site management tool

VitoDeploy v4.0 has just landed. For anyone who hasn't come across it, Vito is a free and open-source server management tool - think of it as a self-hosted alternative to Forge/Ploi for provisioning servers and deploying PHP/Laravel (and Node, Bun, .NET + static) sites - but without features locked behind a paywall.

This release is a big one, with many existing features being expanded and improved, as well as a whole heap of new features as well. A few highlights;

  • GitHub App provider + one-click/automated deployments
  • Automated workflows - create/update/manage sites, servers, etc.
  • Support for Laravel, PHP, Bun, Node, .NET and static sites, and a full plugin system to add more!
  • Per-site PHP runtime settings and a much bigger site tooling story (Composer, cron jobs, commands, required tooling all running as the isolated user).
  • Server Security + Networking (IP management), firewall port ranges.
  • Site stats, service logs viewer, monitoring improvements, and automatic update checks.
  • New storage drivers (SFTP, Dropbox OAuth), Valkey service, a live ssh terminal.
  • Domain + DNS management, through Cloudflare and other providers
  • LetsEncrypt Wildcard SSL registration and automated renewal
  • Light/dark mode support

Loads more in the full changelog - this release has been cooking for a while.

You can self-host it locally using docker, or throw it on a cheap VPS. Worth a look if you're paying monthly for a deploy tool and fancy having more control and full features!

Release notes: https://github.com/vitodeploy/vito/releases/tag/4.0.0

Docs: https://vitodeploy.com

u/andercode — 6 days ago
▲ 12 r/laravel

Release SimpleStats 6.0 - Laravel analytics beyond pageviews (recurring revenue, retention & campaign profit)

Hi folks,

I'm really excited to announce that we just released version 6 of SimpleStats, and it's the biggest update so far!

SimpleStats is a server-side, GDPR-compliant and 100% accurate analytics tool for Laravel apps that goes beyond simple counts of views and visits. It shows you in-depth metrics like Registrations, Conversion Rate, Daily Active Users, campaign ROI, Average Revenue per User, Total Revenue and much more in just a few minutes.

Because the tracking happens server-side, it can't be blocked by ad blockers.

6.0 is all about going from "how much traffic did we get?" to "is this actually working?". Three new areas answer that: recurring revenue, retention, and marketing profit.

Here's what's new:

💰 Full subscription metrics
MRR and ARR at a glance, plus MRR movements that break your growth down into new, expansion, contraction, churn and reactivation. Net & Gross Revenue Retention, Quick Ratio, revenue churn over time, and estimated LTV. Basically your subscription dashboard, but connected to where the customers actually came from.

https://preview.redd.it/b8rlau3jwsah1.png?width=1280&format=png&auto=webp&s=05179f5d9b2fda5f5528ccd977addab302846b8c

📈 Campaign profit tracking
Enter what you spent on a campaign and SimpleStats gives you ROAS, CAC and net profit per channel. Since it already ties revenue back to the campaign that earned it, it can finally answer which campaigns actually make money after ad spend. LTV:CAC and CAC-payback are in there too, so you know which channels are worth scaling.

https://preview.redd.it/rngt2ijlwsah1.png?width=1280&format=png&auto=webp&s=b657b87c59c713021326655206a89274af1e8680

🔁 Retention & engagement
Cohort retention that you can filter by channel, so it's not just "do users come back?" but "which channel brings the users who come back?". Plus stickiness (DAU/MAU) and user churn to keep a pulse on your active base.

https://preview.redd.it/0fkc5f6nwsah1.png?width=1280&format=png&auto=webp&s=0731309c4fd9b5b78567d582349b1e3f757d9aa6

⏱️ Funnel timing
New time-to-convert (first visit → signup) and time-to-pay (signup → first payment) metrics.

👤 Power Users
A new view of your most valuable individual users, ranked by lifetime revenue and activity. See where each one came from, their current plan, total revenue and last login, all GDPR-compliant (users are identified only by the ID your app sends, never a name or email). There's even a one-click impersonate link to jump straight into a user's account in your own app.

https://preview.redd.it/su09qvapwsah1.png?width=1280&format=png&auto=webp&s=1c7f166ce033881903a5061a00a51f91238a0c6a

🎛️ Redesigned dashboard
Cleaner charts and click any metric for a detailed breakdown. The heavy SaaS metrics live in their own Subscriptions, Retention and Campaigns areas, so the main dashboard stays focused.

https://preview.redd.it/hgv4pmb3xsah1.png?width=1280&format=png&auto=webp&s=0f0e2f3109853ae8f9c4f503d9d3e2463cdc8845

⚡ The usual – performance improvements, more polish and various bug fixes.

Feel free to step by and check out SimpleStats at: https://simplestats.io

Thanks for reading,
Zacharias

PS: Your feedback is highly appreciated, as always!

reddit.com
u/Nodohx — 4 days ago
▲ 62 r/laravel

I built a custom E-commerce platform from scratch using Laravel 12 & Vue 3. Seeking feedback!

Hi everyone,

I just finished building a custom e-commerce platform from scratch using the VILT stack (Vue 3, Inertia, Laravel 12, Tailwind CSS).

The main focus of this project was to move away from hardcoded business logic and create a highly flexible, modular system.

Key features:

  • Tech Stack: Laravel 12, Vue 3, Inertia.js, Tailwind CSS.
  • Architecture: Headless-ready approach, modular design.
  • UX/UI: Focused on a clean, dark-themed, and premium user experience.

I’m looking for some constructive criticism on the architecture, code structure, or even the UI/UX. Since this is a personal project I’ve been pouring a lot of effort into, I’d really appreciate an expert eye to point out what I could improve or if there are better patterns I should adopt.

GitHub Repository: https://github.com/andmurturi0/laravel-ecommerce

Looking forward to your thoughts!

u/Dapper-Ad7165 — 9 days ago

Prism PHP Unmaintained, Future AI Libraries?

Hey everyone, figured I'd point out that prism-php is effectively unmaintained. The primary contributor has been MIA since March. It was previously the underlying library behind laravel/ai but was refactored out several versions ago. I'm looking to change libraries and wanted feedback on what people are switching to.

reddit.com
u/x12superhacker — 8 days ago
▲ 20 r/laravel

Show r/laravel: Laravel Tenant Kit — open-source multi-tenant SaaS starter (MIT)

Hi r/laravel — first time posting here. I maintain Laravel Tenant Kit, an open-source starter for building multi-tenant SaaS on Laravel.

WHAT IT IS

One Laravel app: central domain (signup, billing, admin) + workspace subdomains (e.g. acme.yourapp.test). Each workspace gets its own database (Stancl Tenancy).

STACK

Laravel 13 · PHP 8.4 · Filament 5 · Stancl · Cashier (Stripe) · Breeze · Sanctum API · Docker · MySQL/PostgreSQL · Redis

INCLUDED

• DB-per-tenant isolation, subdomain + custom domains

• Auth on central + each workspace

• Teams, roles, invitations

• Stripe subscriptions per workspace

• Filament /admin for platform management

• OAuth (Google/GitHub)

• Central + tenant API tokens (abilities, rate limiting)

• Usage meters (api_calls, team_seats)

• English + Arabic (RTL)

• CI, 71 PHPUnit tests, Docker one-command setup

LATEST (v1.3.1)

Optional in-app guided chat on the central dashboard — create workspaces, check usage, invite teammates. Powered by api-operator on PyPI (Python sidecar; Laravel stays PHP-only).

TRY IT

git clone https://github.com/mohammedelkarsh/laravel-tenant-kit.git

cd laravel-tenant-kit

.\scripts\docker-setup.ps1

Login: http://laravel-tenant-kit.test:8080/login

admin@laravel-tenant-kit.test / password

LINKS

Repo: https://github.com/mohammedelkarsh/laravel-tenant-kit

Release: https://github.com/mohammedelkarsh/laravel-tenant-kit/releases/tag/v1.3.1

Article: https://dev.to/mohammedelkarsh/manage-your-laravel-multi-tenant-saas-from-a-chat-widget-v131-23pd

Demo GIF: https://raw.githubusercontent.com/mohammedelkarsh/laravel-tenant-kit/main/docs/screenshots/demo.gif

MIT. Feedback welcome — especially from anyone building SaaS on Laravel.

u/mohammedelkarsh — 9 days ago

GDPR consent in Laravel is usually a paid CMP or a boolean column. I built the in-between — and just shipped v2.

Every time I had to do "GDPR consent" in a Laravel app, I ended up choosing between two bad options:

  • A paid consent-management SaaS (Cookiebot / Iubenda / OneTrust). Fine for a marketing site, overkill and pricey for an app where consent is part of the domain.
  • A `accepted_terms` boolean on the users table. Five minutes of work, and useless the moment anything real happens.

The thing the boolean misses is that GDPR consent isn't a banner — it's a record you can defend. You need to *prove* consent later (Art. 7(1)), re-ask when the policy version changes, handle revocation, expire and renew, export what a user consented to (Art. 15/20), and erase a person (Art. 17) WITHOUT destroying the proof you collected the consent in the first place. That last one is the contradiction that makes a naive schema fall apart.

So the package is the layer between those two extremes:

  • Typed, versioned consent types with stable slugs — you can tell exactly who has to re-consent after a policy change.
  • An append-only audit trail (granted / revoked / renewed / expired / anonymized) with a snapshot of the policy version + URL + hash. That's the Art. 7(1) proof.
  • Erasure by pseudonymisation: anonymize the subject, keep the audit proof intact.
  • Expiration + renewal, guest (cookie-based) consents for anonymous visitors, data-subject export, and Art. 30 fields (legal_basis / purpose / data_controller) on each consent type.
  • A configurable cookie banner with AJAX accept / reject / save-preferences, if you want the front-end too.

v1 (last year) was honestly just a consent table with timestamps. v2 is the rewrite that turns it into something you'd actually trust under audit: the immutable audit trail, the erasure/export commands, domain events, and a versioning redesign (slug is now a stable group id, one row per version, no more LIKE-based lookups). It has breaking changes — there's an UPGRADE.md.

v2.1 (today) is the part I'm most happy about: I had an independent GDPR auditor do an adversarial pass over both the code and the docs. Result was user-agent minimisation, a stronger erasure path, a fuller export, a real docs site — and I removed the "provably compliant" wording from the README because it was an over-claim. Which leads to the honest part:

What it does NOT do (so nobody ships it thinking they're done):

  • It records cookie choices, it does not block third-party scripts for you. ePrivacy script-gating is still your job.
  • No minors' age mechanism.
  • Audit-log immutability is enforced at the application level (Eloquent), not by the database.

Stack: PHP 8.2–8.4, Laravel 11/12/13, 116 tests, 96.2% coverage, PHPStan level max (no baseline), mutation testing. ~1.3k installs, small but real.

What I'd genuinely like feedback on: is enforcing audit-log immutability at the app layer (overriding Eloquent's update/delete) good enough in your view, or would you push it down to DB permissions / triggers? I went app-level for portability across MySQL/Postgres/sqlite, but I'm not 100% settled.

Repo: https://github.com/Sellinnate/laravel-gdpr-consent-database

Docs (the "why" behind each feature, plus the scope & limitations page): https://laravel-gdpr-consent.selli.io

Packagist: selli/laravel-gdpr-consent-database

Happy to answer anything about the schema or the GDPR reasoning.

u/LongjumpingUse7193 — 9 days ago
▲ 16 r/laravel

Introducing Maverick.bbq version 3: an open-source, BBQ temperature monitor for use with the Maverick ET-732 wireless thermometer

8 years ago I made version 1.

3 years ago I made version 2.

Now I have version 3, and I'm pretty happy with the final product.

Most recent upgrades in version 3:

  • Rewritten completely for Laravel 13 (did not use Laravel before)
  • Websockets for instant updates to chart viewers (using Laravel Reverb)
  • Push Alerts
  • Dark mode support
  • Rich Text Editor and images can be included with each cook
  • Add notes to chart data points
  • Progressive Web App
  • Mobile first design
  • Dark mode
  • Updated stats page (unfinished, but upcoming)

And all of this runs on an original Raspberry Pi Zero W. Laravel with Reverb websockets running on a 512 MB RAM server with a single 1GHz CPU. And guess what, RAM is not the bottleneck, CPU speed is. It's definitely slow on the Pi Zero, but virtually any other Pi with more CPU would be totally fine. I'd love to get a Pi Zero 2W and see if it runs faster.

Let me know if you have any questions!

u/Produkt — 9 days ago

Long overdue, Filament v5 support is finally here for json-column & sketchpad!

Hey all, I know many of you have been relying on filament-json-column, and I'm sorry it took this long to get here.

Life got in the way (moving, job, etc...), and the plugin fell behind on Filament v5 and accumulated a lot of open PRs and issues. That's now been addressed.

What's new in this release:

  • Filament v5 compatibility
  • Bug fixes
  • Multilingual support

I've also updated filament-sketchpad while I was at it.

Thanks for your patience, and happy coding!

github.com
u/andre_ange_marcel — 9 days ago
▲ 33 r/laravel

Architecture DeepDive: How We Are Processing 1B+ Events Per Month With Minimal Performance Impact

Hi everyone,

I’m the creator of Laritor. A performance monitoring and observability tool designed specifically for Laravel.

I wrote a detailed blog post about how we architected the observability ingestion pipeline to process and store millions of events.

I hope you would enjoy reading this as this is not a typical performance optimization blogpost for regular laravel applications.

Happy to answer any questions.

laritor.com
u/sribb — 11 days ago
▲ 38 r/laravel+1 crossposts

This Week In PHP Internals | June 24, 2026

Hello world, it's Wednesday, June 24, 2026, and here's what happened This Week in PHP Internals.

This week's episode is supported by Ballast — our new gauge for whether the software you ship actually lasts. Velocity tells you how fast you ship; Ballast tells you whether it stayed shipped — one durability score, read straight from your git history. No survey, no black box. Early access opens at artisan.build/ballast.

Right — Gina P. Banyard opened the annual Deprecations for PHP 8.6 RFC. It's the yearly omnibus: a year's worth of small removals, compiled by a dozen hands, each one voted on its own, and it has to be frozen by July 13. This year the sharpest exchange wasn't about any one removal — it was about evidence. Juliette Reinders Folmer pressed the point that the proposals ship without an impact analysis: "[N]one of the proposals contain a proper impact analysis," she wrote, calling it irresponsible to ask voters to decide partly blind — and she offered to build one, PHP_CodeSniffer plus PHPCompatibility, covering most of the list.

Tim Düsterhus pushed back — said the claim wasn't accurate, and reminded the list that deprecations aren't a breaking change. Juliette felt that talked past her, and answered plainly: "Tim, please don't try to gaslight me." It's worth sitting with, not laughing past: underneath the heat is a fair ask — give voters the data to decide. And by midweek it wasn't a two-person spat — Rowan Tommins backed the substance. A deprecation, he argued, is really a proposal to remove something later, so the impact of that removal is fair to weigh; he put it bluntly: "To knowingly omit information that might weaken your case would be dishonest."

So what's actually proposed for removal? A real grab-bag, each with its own argument. The _() shorthand for gettext() — and Rowan Tommins flagged that one as genuinely costly, since _() is the canonical gettext spelling and big codebases lean on it thousands of times. Reserving the keywords let, in, out, and inout. The CURLOPT_PROGRESSFUNCTION constant — where Ayesh Karunaratne argued don't deprecate it at all, just quietly remap it onto CURLOPT_XFERINFOFUNCTION and spare a few hundred maintainers the churn. Plus spl_object_hash() and metaphone().

One fresh proposal rode in on that same thread. Muhammed Arshid KV wants to deprecate SplFileObject's CSV methods — fgetcsv, fputcsv and the rest — in favour of a dedicated csv extension. But Ignace Nyamagana Butera, who maintains the league/csv library, hit the brakes: "deprecating the current API without providing at least the start of a replacement API seems premature [...] Anything else would be counterproductive at the moment." Gina's standing offer to anyone with an idea: send me the text and I'll fold it in — but I'm not writing it for you.

The single busiest thread of the week, though, was brand new. Tim Düsterhus and Derick Rethans proposed a Time\Duration class — a first-class, immutable stopwatch value, deliberately small, aimed at 8.6 so it can smooth the new Polling API's timeouts before the feature freeze. And it's the opening move of a modern date-and-time API. Fifty-some replies followed, almost all the productive kind of argument: should a negative duration carry a sign flag or just be signed seconds? What on earth do you call dividing one duration by another? Marc Bennewitz pushed hard on the representation; Paweł Kraśnicki showed up from the brick/date-time world and got a warm "welcome and thank you for contributing."

When the design drifted toward a static Duration::sum(), Larry Garfield drew a firm line: "I am 100% against a static method for adding durations. That's entirely pointless." He wants $dur1->add($dur2)like a civilized person. By Tuesday Tim had already renamed the ISO parser and added an ->absolute() method, so this one is genuinely moving.

Rob Landers opened a pre-RFC for Primary Constructors, lifted out of his old Records proposal. Picture the whole constructor promoted up onto the class line itself. The catch in Rob's version: a class with one can't also declare a __construct, so real init logic has to run through property hooks — and Nick Sdot caught the snag immediately, that hooks-only means the class can't be readonly. Larry's in, keep-it-simple, with a side of Kotlin. Rowan Tommins pushed back: "I don't think we should add extra syntax to the language just to change people's habits."

Function autoloading came back for a fifth try — Paul Jones's mark 5 of a feature internals keeps almost-shipping and never quite does. It drew the exact objection that's sunk every prior run: lean on it, forget to fully-qualify a name, and your code works by accident because something else loaded that function first — then breaks silently after a refactor. Tim Düsterhus put it flatly: "Agreed on this being a non-starter for the proposal for me." Paul's answer is a declare(strict_namespace=1) switch to kill the global fallback, plus a patient reply to Bob Weinand on why the engine simply can't retry name resolution cheaply.

To the ballots. The headline features still can't find a two-thirds. Seifeddine Gmati's Bound-Erased Generics is, as of this recording, sitting at 7 in favour, 19 against, 10 abstaining — and that's the primary; on the syntax sub-vote the C#-style in/out spelling is killing it, 24 to 2. Nicolas Grekas's __exists() magic method is underwater too, 2 to 12 with 7 abstentions. And Daniel Scherzer read the room on ReflectionAttribute::getCurrent() — stuck at 4-7-8 — and simply pulled the vote to rework it.

The focused changes, meanwhile, are clearing without a single No. Tim Düsterhus's deprecation of returning values from constructors and destructors: 37 to nothing as of recording. Sjoerd Langkemper's cap on php://filter chains — last week's local-file-inclusion-to-RCE fix — running 30 to nothing, 2 abstaining. Weilin Du's Locale display-keyword additions are in — the vote closed and the RFC's accepted, 18 to nothing. And Jordi Kroon's plan to lift third-party extension docs out of the manual is cruising at 21 to 1 — though the room is split on where they should live.

Tough week to be a revival. Jorg Sowa brought back case-sensitive PHP, took a full week of fire — Rob Landers didn't hedge: "I honestly can't think of anything good that this RFC would bring" — and on Tuesday retired it himself, writing: "I'm sorry, but I'm going to stop work on this RFC. I see very little chance it passing." James Titcumb formally walked away from the deprecate-PEAR RFC, realising it isn't really the project's call to make, and explained: "[D]eprecating PEAR is not really within the remit of the wider PHP community [...] it's like making an RFC to deprecate Packagist." Quieter movers: Literal Scalar Types reached v0.2 with strict matching by default, and the .phpc pure-code idea mutated into an alternate opening tag, <?psf, that could even carry a new_scope directive.

On the governance bench: Khaled Alam's "write to objects held in constants" RFC cleared its cooldown and is headed to a vote June 29. And Ben Ramsey reshaped the Working Groups proposal — moving the real policy text out into a pull request so the RFC itself is just charter-and-link — still trying to give the project a little structure without crowning a BDFL.

One human note to end on. A few weeks back a newcomer, Sepehr Mahmoudi, floated a get_favicon() function and got the classic "what problem does this actually solve" welcome. This week he withdrew it himself — better suited to userland, he decided — pivoted to a str_mask() helper, heard Rowan explain that real masking needs graphemes and ICU rather than raw bytes, and pivoted again to grapheme_mask() for the intl extension, working C prototype in hand. And as of this morning he's got the keys to write it up — Ilija Tovilo granted his RFC karma and signed off with a simple "Good luck!" That's the list at its best: someone turning up, listening, and getting better in the open.

Quick hits. Sjoerd Langkemper is everywhere this week — beyond the filter-chain vote, he wants base_convert to stop silently shredding entropy when you build random tokens with it, and he's adding a ValueError for invalid characters to hexdec, bindec and octdec. Osama Aldemeery floated deprecating return inside a finally block — the one silent abrupt-exit PHP still allows — backed by an impact analysis showing it hits just 12 sites across 9 packages, 3 of them actual latent bugs; it's folding into the omnibus. Pratik Bhujel's terminal extension reached v0.5.0. Gianfrancesco Aurecchia floated an Openssl\Dtls class to bring DTLS — the UDP side of TLS, the piece WebRTC needs — into the openssl extension, proof-of-concept already green. And 8.4.23 and 8.5.8 both cut release candidates.

That's the week: a deprecations RFC that became an argument about evidence and respect, a stopwatch class that swallowed the mailing list, two revivals laid to rest, and the headline votes still stalled while the small ones glide through. Links to every thread are below. We're Artisan Build. See you next week.

youtube.com
u/ProjektGopher — 11 days ago
▲ 31 r/laravel+1 crossposts

I ran a performance audit on my Laravel app and found 12 fixes. Here are the ones that actually moved the needle

I spent a week digging into why my 8 GB VPS was sitting at 90%+ memory usage.

LaraPlugins.io indexes 76,000+ packages with Horizon workers running 24/7, so the usual tips did not quite apply.

The biggest wins were not clever architecture changes. They were cleanup:

The 50,000-job problem that should never have existed

During weekly health recalculations, every updated plugin dispatched a Cloudflare cache purge job. Fifty thousand individual Redis pushes hitting the queue at once. The fix? A Redis SADD set that collects paths, then a single self-rescheduling job that flushes them in batches of 30 via the bulk API. One job instead of 50,000, with free deduplication.

Horizon supervisors doing too much

Unlimited maxJobs meant workers leaked memory until the OOM killer stepped in. Generic queue names like "low" and "analytics" made debugging slower. Split the maintenance monolith into dedicated supervisors (github-sync, health, background) with explicit maxJobs and memory caps. Dropped the memory ceiling by roughly 2 GB.

The column nobody reads

A JSON metadata column was loaded on every Plugin model query, even by jobs that only write to it. A global scope to exclude it by default cut query payloads significantly. Took 10 minutes to add. Should have been there from day one.

Three obvious missing indexes

plugin_versions version columns, failed_jobs.queue, and a vendor detail page path. Not exotic compound indexes. Single-column indexes I forgot to add when the tables were created.

Full breakdown with numbers for each fix in the post.

danielpetrica.com
u/HolyPad — 14 days ago