To some developers this feels like a cleaner syntax:
#[Fillable(['name', 'email'])]
#[Table('users')]
class User extends Model
{
//
}Others looked at the same code and asked a simple question:
“Why replace perfectly fine properties with attributes?”
That tension is interesting because it reveals something deeper about Laravel itself. Laravel has always balanced two competing ideas:
- expressive developer experience
- pragmatic simplicity
Laravel 13’s new attribute-based model configuration pushes hard toward expressiveness and modern PHP conventions. But many developers are unconvinced that it actually improves maintainability.
What Changed in Laravel 13?
Historically, Eloquent model configuration lived in protected properties:
class User extends Model
{
protected $table = 'users';
protected $fillable = [
'name',
'email',
];
protected $timestamps = false;
}Laravel 13 now allows these to be declared using PHP Attributes instead:
use Illuminate\Database\Eloquent\Attributes\Table;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Attributes\WithoutTimestamps;
#[Table('users')]
#[Fillable(['name', 'email'])]
#[WithoutTimestamps]
class User extends Model
{
//
}Laravel also introduced attributes for scopes:
#[Scope]
protected function active(Builder $query): void
{
$query->where('active', true);
}The official documentation positions this as a cleaner and more modern API.
Why Some Developers Like It
There are legitimate advantages.
1. Better Alignment With Modern PHP
PHP Attributes are now part of the language ecosystem.
Many modern PHP Frameworks and libraries already use attributes heavily.
Laravel adopting them signals that the framework is evolving with modern PHP rather than staying tied to older patterns.
For developers coming from other ecosystems, this feels natural.
2. Configuration Becomes More Declarative
Attributes separate metadata from implementation details.
Compare:
protected $fillable = ['name'];
vs
#[Fillable(['name'])]
The second version reads more like explicit model metadata than mutable runtime state. Since nothing in the application can modify this attribute it is implied as static configuration. With properties in a class anything can modify this property on the fly in real time.
That distinction matters philosophically, even if functionally they achieve similar outcomes.
3. Reduced Property Clutter
Large Eloquent models often become walls of configuration:
protected $fillable = [];
protected $casts = [];
protected $hidden = [];
protected $appends = [];
protected $with = [];Attributes can visually compress that setup into something easier to scan.
Especially in models with lots of business logic, removing configuration noise can improve readability. Properties are also not part of a interface, so if Laravel decides to rename a property, the original property will not throw an error. If Laravel would rename an Attribute class, the code would crash instantly.
4. Attributes Work Well for Discovery
IDE tooling increasingly understands attributes well.
Attributes are also easier to inspect programmatically through reflection than parsing class properties or docblocks manually. For example if you want to figure out relations etc. of a eloquent model any tool had no other option in calling all methods on the model and see if a relation object is returned.
That opens doors for future tooling, static analysis, code generation, and AI-assisted frameworks.
Why Many Developers Are Skeptical
This is where the debate becomes more interesting.
Because the criticism is not just “people dislike change.”
A lot of developers genuinely believe the attribute approach is solving a problem that barely existed.
1. Properties Were Already Simple
One of the most common reactions was:
“What benefit does this actually provide?”
That sentiment appeared repeatedly in community discussions around Laravel 13.
The old syntax was already extremely readable:
protected $fillable = ['name'];
Replacing it with:
#[Fillable(['name'])]
does not obviously reduce complexity.
In some cases, it arguably increases it.
2. It Creates Multiple Ways To Do The Same Thing
Laravel has historically struggled with “there are five ways to do this.”
Attributes add yet another configuration style.
Now teams must decide:
- properties?
- attributes?
- traits?
- fluent APIs?
- conventions?
Consistency inside a team matters more than syntax aesthetics.
And introducing parallel patterns increases cognitive overhead.
3. Reflection-Based Systems Feel More “Magic”
Laravel already gets criticized for being too magical.
Attributes rely heavily on PHP reflection internally.
Some developers are uncomfortable with moving even more framework behavior into metadata discovery systems rather than explicit code.
As I found on Reddit:
“Java all over again with unreadable annotations.”
That may be exaggerated, but the concern is real.
4. Runtime Overhead Concerns
A few developers raised performance concerns because attributes require reflection.
Technically, reflection is slower than direct property access.
Practically, though, the performance difference is probably irrelevant in real-world Laravel applications because metadata gets cached aggressively. This is very true when opcache is enabled.
Still, even if performance is negligible, some developers question the tradeoff:
if readability is not significantly improved, why add additional abstraction layers?
That’s a fair engineering question.
5. Laravel’s Strength Was Pragmatism
This may be the biggest underlying concern.
Laravel became popular because it often chose practical solutions over academically “pure” architecture. Eloquent itself is intentionally straightforward.
Properties felt simple and attributes feel more framework-heavy.
Some developers worry Laravel is drifting toward “enterprise framework” territory where metadata annotations gradually dominate the codebase.
That fear may be overstated, but it explains the emotional reaction many people had.
The Important Detail Most Discussions Miss
The new attribute system is largely an alternative. Laravel did not remove property-based configuration.
This matters as you can still write:
protected $fillable = ['name'];
and Laravel 13 works perfectly.
That means the debate is less about forced migration and more about preferred coding style.
In practice, most teams will probably settle into one of three camps:
| Team Style | Likely Outcome |
|---|---|
| Conservative Laravel teams | Keep using properties |
| Modern PHP-oriented teams | Adopt attributes heavily |
| Mixed teams | Use attributes selectively |
And honestly, selective usage may become the healthiest middle ground.
Where Attributes Actually Make Sense
Not every Eloquent feature benefits equally from attributes.
Some uses genuinely feel elegant.
For example, scopes:
#[Scope]
protected function active(Builder $query): void
{
$query->where('active', true);
}This is arguably cleaner than relying on naming conventions like scopeActive(). The same could be applied to relations and appending fields.
Attributes also work well for metadata-style declarations:
- table names
- timestamp configuration
- fillable rules
- observers
- event registration
These are truly declarative concerns.
Where Properties Still Feel Better
Mutable configuration still feels more natural as properties.
For example:
protected $casts = [
'settings' => 'array',
];This reads naturally because it behaves like application state configuration.
Turning everything into attributes risks making ordinary model configuration feel overly ceremonial.
The Real Question Isn’t “Better or Worse”
The real question is:
Does this improve code comprehension for your team?
That answer depends heavily on context.
A senior PHP team already comfortable with attributes across the ecosystem may find Laravel 13 cleaner and more consistent.
A Laravel-first team may see little practical benefit.
Is there a behaviour difference?
class NewModel extends BaseModel {};
Final Verdict
Laravel 13’s Eloquent Attributes are neither revolutionary nor disastrous.
They are mostly:
- a modernization effort
- a consistency improvement
- a stylistic evolution/syntactic sugar
The criticism is understandable because the old property-based approach was already understandable for most developers, even though there are more robust solutions from a design perspective.
Attributes mostly change how Laravel expresses metadata.
For some developers, that feels cleaner.
For others, it feels unnecessary.
My expectation is that the Laravel ecosystem will eventually land on a hybrid approach:
- attributes for declarative metadata
- properties for mutable configuration
- conventional methods for behavior
And honestly, that balance probably makes the most sense.

Comments
Post a Comment