Skip to main content

Overview

Every time an Eloquent model is instantiated it runs two phases: boot (once per class) and initialize (once per instance). When you define specific methods in a trait, Eloquent automatically discovers and calls them. Adding the trait to a model is all that’s needed. Laravel itself uses this pattern extensively in traits like SoftDeletes, HasUuids, and HasUlids.

boot vs. initialize


Naming Conventions

bootXxx()

Define a static method prefixed with boot followed by the trait’s class basename. Eloquent calls it once per class lifecycle.
Using the trait in a model:

initializeXxx()

Define an instance method prefixed with initialize followed by the trait’s class basename. Eloquent calls it every time a new instance is created.
Dynamically merging casts is another common use:

PHP Attributes

Since Laravel 12, you can use PHP Attributes instead of relying on naming conventions.
Using PHP Attributes frees your method names from the trait-name constraint. You can also define multiple #[Boot] or #[Initialize] methods within the same trait.

Practical Examples

Adding a Global Scope Automatically

Merging Default Casts

Auto-archiving on Delete


Examples in the Framework

Laravel’s own traits demonstrate the pattern clearly: Reading these implementations is a great way to understand the pattern in depth.

Caveats

Clearing Booted Models in Tests

Because boot* runs only once per class, tests that alter model behavior may need to reset the boot cache:

Execution Order

When a model uses multiple traits, bootXxx() and initializeXxx() are called in PHP’s trait resolution order (declaration order). Be mindful of ordering when traits depend on each other.

Summary

Implementing bootXxx() and initializeXxx() in a trait lets you inject behavior into any Eloquent model with a single use statement — the go-to pattern for package authors.
Last modified on July 15, 2026