# essentials, a Laravel package that changes the framework's defaults

> essentials is a Composer package for Laravel that makes the framework stricter by default, with models that throw on undefined attributes, relationships eager loaded automatically, dates made immutable, and a console that refuses to run destructive commands in production. Every feature can be switched off, but the package changes how the framework behaves underneath you.

**nunomaduro/essentials** — Just better defaults for your Laravel projects.

- Repository: https://github.com/nunomaduro/essentials
- Website: https://youtube.com/@nunomaduro?sub_confirmation=1
- Stars: 1,245 · Forks: 75
- Language: PHP
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/nunomaduro-essentials

## Defaults you would otherwise have to enforce yourself

essentials is described in one line as providing better defaults for Laravel applications, including strict models, automatically eagerly loaded relationships, immutable dates and more. The requirements are stated up front, PHP 8.3 or later and Laravel 11 or later. Then comes the caveat that decides whether the package is for you, which is that it modifies the default behaviour of Laravel and that it is recommended to use it in new projects, or when you are comfortable with the changes it introduces. That is an unusual admission for a package whose whole purpose is to change behaviour, and it tells you the shape of the trade. The audience is a team that has already agreed these defaults are the right ones and wants them applied consistently rather than argued about in review, and the counter case is an established codebase with packages that rely on the looser behaviour.

## Strict models and eager loading without the with() calls

The strict models feature changes how Eloquent handles three specific things. Accessing a missing attribute throws an error, lazy loading is blocked unless it is explicitly allowed, and setting an undefined attribute throws instead of failing silently. The stated reason is to avoid subtle bugs and to make model behaviour easier to reason about, and the third point is the one that bites hardest in an existing codebase, because the silent case was often the case your code relied on. Auto eager loading sits next to it and is the friendlier feature. It automatically eager loads the relationships defined in the model's $with property, and the reason given is that it reduces N+1 query issues and improves performance without needing with() everywhere. For a team that already uses $with on a few models, this is free, and for a team that does not, it is a change in how many queries a page makes.

## The three switches you opt into

Three further features are the ones with the widest blast radius. Optional unguarded models disables Laravel's mass assignment protection globally, and the reason given is that it is useful in trusted or local environments where you want to skip defining $fillable, which is exactly why it is a switch rather than a default. Immutable dates uses CarbonImmutable instead of mutable date objects across the application, and the reason is that it prevents unexpected date mutations and improves predictability, which is a quiet but real source of production bugs in Laravel applications. Force HTTPS forces all generated URLs to use the https scheme, and the reason is that it ensures traffic uses secure connections by default. Each of the three is a change in behaviour that a codebase either wants or fights, and the configuration file is where that fight gets settled.

## A console that refuses, and tests that cannot wander

The safe console feature blocks potentially destructive Artisan commands in production, with migrate:fresh named as the example, and the reason is to prevent accidental data loss and to add a safety net in sensitive environments. That is a guard rail rather than a fix, and it is the feature most likely to surprise an existing deployment, since a deployment script that runs a command you did not know was blocked will fail in a way that looks like a bug in your code. The testing features are the opposite in tone. Prevent stray requests configures the Laravel Http facade so that every HTTP call during tests has to be explicitly faked, with the stated aim that every HTTP call during tests is explicitly faked. Fake sleep configures the Laravel Sleep facade to be faked, to avoid unexpected sleep during test cases. Asset prefetching is a front end change rather than a guard rail, configuring Laravel Vite to preload assets more aggressively.

## Commands that generate code and publish tool configs

The package adds three Artisan commands, and they are the part a team will actually type. make:action generates an action class, and the example shows the shape it produces, a final readonly class in app/Actions with strict types declared and the work wrapped in a database transaction.

```bash
php artisan make:action CreateUserAction
```

The other two publish configuration for external tools. Laravel Pint is included by default in every Laravel project, but configured very minimally, and essentials:pint publishes a configuration that enables declare_strict_types, final_class, ordered_class_elements and strict_comparison, and more.

```bash
php artisan essentials:pint {--force} {--backup}
```

essentials:rector does the same for Rector, publishing a configuration with the deadCode, codeQuality, typeDeclarations, privatization, earlyReturn and strictBooleans rules.

```bash
php artisan essentials:rector {--force} {--backup}
```

Both take a --force flag that overwrites the existing configuration without asking and a --backup flag that keeps a copy of what was there before, which is the sensible way to introduce a house style into a repository that already has one.

## The configuration file is a map of classes

Everything the package does is controlled from one file, config/essentials.php, and the file is a map from configurables to booleans.

```php
// config/essentials.php
return [
    NunoMaduro\Essentials\Configurables\ShouldBeStrict::class => true,
    NunoMaduro\Essentials\Configurables\Unguard::class => false,
    // other configurables...
];
```

The keys are class names, so the configuration reads as a list of decisions rather than a list of strings, and the naming is the setting name, which makes a diff of the file readable on its own. By default most features are enabled, and any of them can be disabled by setting its value to false. The file is published with the standard Laravel vendor publish command, and the package also ships stubs you can publish separately.

```bash
php artisan vendor:publish --tag=essentials-config
php artisan vendor:publish --tag=essentials-stubs
```

The repository layout follows the same logic, with src/ for the implementation, config/ and stubs/ for the published files, tests/ running under a testbench.yaml, and the tool configuration checked in as pint.json, rector.php, phpstan.neon.dist and phpunit.xml.dist, so the package's own standards are visible in the tree.

## Versions, licence and who this is for

The licence is MIT, the package is on Packagist as nunomaduro/essentials, and the release history shows the project settling into its first stable line, with v1.0.1 in September 2025, v1.1.0 in February 2026 and v1.2.0 a few days later. The repository is not archived and the last push was on 2026-10-14, so it is being maintained. The limitation is the one the README states plainly, that the package modifies default Laravel behaviour, which means that adopting it in an application with a large dependency tree is a compatibility exercise rather than an installation. In practice the features interact. Strict models and auto eager loading change what your queries do, immutable dates change what your code does with time, and force HTTPS changes what your URLs look like in emails and generated links. A team that wants only one of these can enable only one, since the configurables are independent. The judgement for an adopter is whether the defaults are ones you would choose anyway, because that is exactly the question the package is making you answer once.

## Conclusion

essentials fits a team starting a new Laravel application that wants the strictness decisions made once rather than in every review, and it fits a team that has already adopted the same habits by hand and wants them encoded in configuration. It does not fit an existing application with third party packages, because the package modifies default behaviour and the documentation itself recommends using it in new projects or where you are comfortable with the changes. Verify three things first: that your Laravel version is 11 or newer and your PHP is 8.3 or newer, since those are hard requirements, which of the configurables you actually want on, since the defaults enable most of them, and what happens in production, because the safe console and the forced HTTPS behaviour are the two settings most likely to surprise an existing deployment.

## FAQ

### What is the nunomaduro/essentials package?

It is a Laravel package that provides better defaults for applications, including strict models, automatically eagerly loaded relationships, immutable dates, forced HTTPS, a safe console and testing helpers. It requires PHP 8.3 or later and Laravel 11 or later, and every feature can be disabled in config/essentials.php.

### Does essentials change default Laravel behaviour?

Yes, and the README says so explicitly, recommending that you use it in new projects or when you are comfortable with the changes it introduces. Strict models block lazy loading and throw on undefined attributes, the safe console blocks destructive Artisan commands in production, and force HTTPS changes generated URLs.

### How do I configure or disable the features?

Publish the configuration with php artisan vendor:publish --tag=essentials-config and edit config/essentials.php, which returns a map of configurable classes to booleans. Most features are enabled by default, and setting one to false disables it. The package stubs can be published separately with the essentials-stubs tag.

### What commands does the essentials package add?

make:action generates a final readonly action class under app/Actions, essentials:pint publishes a Pint configuration enforcing declare_strict_types, final_class, ordered_class_elements and strict_comparison, and essentials:rector publishes a Rector configuration with deadCode, codeQuality, typeDeclarations, privatization, earlyReturn and strictBooleans. The last two accept --force and --backup flags.

## Sources

- [License: MIT](https://github.com/nunomaduro/essentials/blob/main/LICENSE)
- [nunomaduro/essentials on GitHub](https://github.com/nunomaduro/essentials)
- [Project website](https://youtube.com/@nunomaduro?sub_confirmation=1)
- [README](https://github.com/nunomaduro/essentials/blob/main/README.md)
- [Releases](https://github.com/nunomaduro/essentials/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/nunomaduro-essentials
