# Laravel Conventions

> Personal Laravel conventions enforced when creating, modifying, or planning code that will touch code utilizing the Laravel framework.

- Skill: `cosmastech/laravel-conventions` (Agent Skill)
- Install (CLI): `npx skillmds@latest add cosmastech/laravel-conventions`
- Raw SKILL.md: https://api.skillmd.com/api/skills/cosmastech/laravel-conventions/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: cosmastech (https://skillmd.com/u/cosmastech)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/cosmastech/laravel-conventions

---


# Laravel Conventions

These are non-negotiable personal conventions unless explicitly overridden by the user.

## Models

**No model observers, ever** — Never use Laravel model observers or listen for Eloquent model events (`creating`, `saved`, etc.). Dispatch explicit domain events instead. This is non-negotiable. If they already exist for a given model, mention it to the user, but keep building.

If you are adding **timestamps with millisecond precision**, make sure that you write a `$dateFormat` on the model or in the cast. Otherwise, the precision is silently discarded on DB writes.

**Always set the `$table` value**. This avoids Laravel having to compute the table name every time it's needed.

## Logging

Use `Context@scope()` liberally if important contextual data exists in a parent but not within the children, and the children are writing logs. This allows for maintaining contextual information inside of function calls without needing to pass that data to child functions.

```php
Context::scope(function() use ($user) {
    Context::add('user', $user->id);

    $this->somePrivateMethod($user);
    // ...
});
```

## Helper Methods

Prefer `new Collection()` over `collect()`. This reduces both a stack frame and indirection.

Using `tap()` is rarely the right call for readability.

Prefer `CarbonImmutable::now()` over `now()`.

## Dependency Injection

Prefer dependency injection to using facades. For large projects, test suite time is always a concern, and using facades disallow writing pure PHPUnit tests.

## Testing

Use `Model::factory()->make()` (or `new Model(['property_1' => 'some-value'])`) whenever possible. Database writes are often unnecessary inside of tests.

