There's a take going around, and I've caught myself arguing for it more than once: now that a model can write in thirty seconds what used to take an afternoon, most packages have become pointless. Keep a handful of essentials, generate the rest, own your code.

I think the instinct behind it is right and the conclusion is wrong. Not because packages are still as valuable as they were, but because we're measuring the wrong thing. We always have.

We only ever installed packages for two reasons

Every dependency you've ever added to a composer.json was justified by one of two arguments:

  1. "I don't want to write this." Time, effort, boilerplate. Someone already solved it, why solve it again.
  2. "I don't want to own this." Security patches, framework upgrades, edge cases discovered by ten thousand other people in production, formats that fight back.

For fifteen years these two arguments arrived together, so nobody bothered separating them. A package saved you the writing and the owning, and the bundle looked like a single value proposition.

AI destroyed the first argument almost completely. It didn't touch the second one at all.

That's the whole thing. That's the entire recalibration.

The first argument is gone, and good riddance

The classic dependency pathology was importing something that does one hundred percent of a problem in order to use five percent of it. You needed a slug generator and you got a package with four config files, a service provider, a facade, and an opinion about how you should structure your models. You accepted the surface area because the alternative was writing it yourself, and writing it yourself was expensive.

Writing it yourself is no longer expensive. Which means every package whose entire pitch was "this saves you typing" has quietly become a bad trade. You're still paying:

  • a version constraint that will eventually block your PHP or Laravel upgrade
  • a changelog you have to read
  • an abandonment risk
  • an abstraction your team has to learn instead of reading twenty lines of your own code

...and you're getting back something you could have generated over a coffee. That's not a dependency, that's a liability with a nice README.

Micro-packages, thin HTTP wrappers, helper collections, boilerplate generators, scaffolding kits: this entire tier has lost its reason to exist. If your only defence of a dependency is "it would have been annoying to write," delete it.

The second argument didn't move an inch

Here's what a model doesn't do for you.

It doesn't wake up when a CVE drops. It doesn't know that a maintainer pushed a fix at 2am because someone found a way to bypass a permission check under a specific combination of guards and teams. It doesn't rewrite your code when Laravel 13 changes a contract. It writes the happy path, confidently, and then it goes away.

Take spatie/laravel-permission, since it's probably in most of your projects. Ask a model for a roles-and-permissions layer and you'll get something that works. What you won't get is the eight years of accumulated corrections underneath the real thing: the cache invalidation strategy, the wildcard resolution, the team scoping, the dozens of edge cases that only surface when a few hundred thousand applications hammer the same code. You're not importing 800 lines. You're importing everything that was learned by getting those 800 lines wrong first.

And there are domains where generated code isn't merely worse, it's actively dangerous:

  • Crypto and auth. JWT validation, OAuth flows, signature verification. The failure mode is silent and the blast radius is your entire user base.
  • Hostile format parsing. PDF, XLSX, XML, anything where the input is attacker-controlled and the spec is a horror story.
  • Third-party SDKs. Stripe, AWS, whatever. Their API changes underneath you, and the vendor SDK is the contract that absorbs the change.

In these areas "I had it generated" isn't ownership. It's an unfunded maintenance obligation you've taken on without noticing.

The counterintuitive part

There's a second-order effect worth sitting with: AI works better on code it has seen a lot of.

A model writes Livewire, Filament, and Eloquent well because it has seen an enormous amount of all three. It writes your bespoke internal abstraction badly, because the only thing it knows about your abstraction is whatever fits in the context window right now.

So the strategy of "replace popular packages with proprietary code, the AI will help me maintain it" is partly self-defeating. Every step away from widely-adopted conventions reduces the leverage you get from the tool you're justifying the move with. Popular dependencies aren't just battle-tested anymore, they're legible — to your new colleagues and to your assistant alike.

A test that actually works

Before adding anything, ask one question:

If this package disappeared tomorrow and I had to own its code forever, what exactly would I be signing up for?

If the answer is "twenty lines I'd never think about again" — don't install it. Generate it, read it, own it, move on.

If the answer is "a spec I don't want to implement, a threat model I don't want to reason about, or a vendor API that will change without asking me" — install it, and be glad someone else is on call.

That's the whole framework. It sorts a composer.json faster than any amount of arguing about dependency counts.

What this means in practice

Your dependency list should get shorter. I genuinely believe that, and I think most Laravel projects are carrying ten to twenty packages that no longer justify themselves.

But it should get shorter from the bottom, not the top. Cut the conveniences. Keep the ones absorbing risk on your behalf — the security-sensitive, the format-hostile, the vendor-coupled, the ones with a decade of scars.

The result isn't "fewer packages because AI." It's a dependency list where every remaining entry answers the same question: what am I refusing to own, and why?

Fifteen years ago that question had a lazy answer available. Now it doesn't. That's the actual change, and it's a good one.