PHPackages                             dangerwayne/laravel-specifications - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. dangerwayne/laravel-specifications

ActiveLibrary

dangerwayne/laravel-specifications
==================================

Elegant specification pattern implementation for Laravel with support for Eloquent queries and in-memory filtering

v0.4.0(7mo ago)418.2k—2%1MITPHPPHP ^8.0CI passing

Since Aug 24Pushed 7mo agoCompare

[ Source](https://github.com/dangerwayne/laravel-specifications)[ Packagist](https://packagist.org/packages/dangerwayne/laravel-specifications)[ Docs](https://laravel-specifications-doc.netlify.app)[ RSS](/packages/dangerwayne-laravel-specifications/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (8)Versions (9)Used By (0)

[![Laravel Specifications](https://camo.githubusercontent.com/db573b1b0c104aff4d168ebd989d6a40407e434daffa3989c0dec9cd05c16a35/68747470733a2f2f6c61726176656c2d73706563696669636174696f6e732d646f632e6e65746c6966792e6170702f6c6f676f2e737667)](https://camo.githubusercontent.com/db573b1b0c104aff4d168ebd989d6a40407e434daffa3989c0dec9cd05c16a35/68747470733a2f2f6c61726176656c2d73706563696669636174696f6e732d646f632e6e65746c6966792e6170702f6c6f676f2e737667) Laravel Specifications
==========================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

[](#-laravel-specifications)

A powerful implementation of the Specification Pattern for Laravel applications.

[![Tests](https://github.com/dangerwayne/laravel-specifications/actions/workflows/tests.yml/badge.svg)](https://github.com/dangerwayne/laravel-specifications/actions/workflows/tests.yml)[![Latest Version](https://camo.githubusercontent.com/7a4ab1adc4a124e38771d68d4cbf7c9c0e70e3725ab5d65bca4843e7dd39caa5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f64616e6765727761796e652f6c61726176656c2d73706563696669636174696f6e732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/dangerwayne/laravel-specifications)[![Total Downloads](https://camo.githubusercontent.com/6a87fe5bd6f729e7103517ef58a89b5ba7a5152c60d3483af8af06e5fbb45367/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f64616e6765727761796e652f6c61726176656c2d73706563696669636174696f6e732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/dangerwayne/laravel-specifications)[![Documentation](https://camo.githubusercontent.com/95d544f78f2e43b2159ae282e79ccedebcff0a360b2b08cb1828e9a2417f462e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f63732d72656164792d677265656e2e7376673f7374796c653d666c61742d737175617265)](https://laravel-specifications-doc.netlify.app)

📚 **[Full Documentation](https://laravel-specifications-doc.netlify.app)** | 📦 [Packagist](https://packagist.org/packages/dangerwayne/laravel-specifications) | ⚡ [Quick Start](https://laravel-specifications-doc.netlify.app/quick-start/)

Features
--------

[](#features)

- **Artisan Generator**: Create specifications with `php artisan make:specification`
- **Eloquent Integration**: Seamlessly works with Laravel's Eloquent ORM
- **Collection Support**: Filter in-memory collections using the same specifications
- **Fluent Builder**: Intuitive API for building complex specifications
- **Composite Operations**: Combine specifications with AND, OR, NOT operations
- **Caching Support**: Built-in caching for improved performance
- **Laravel 9, 10, 11, 12**: Full compatibility with modern Laravel versions
- **Type Safe**: Full PHP 8.0+ type declarations and PHPStan level 6+ compliance

> **Note**: The `NOT` specification has full functionality in Laravel 10+. In Laravel 9, it provides basic compatibility with limited SQL generation capabilities.

Installation
------------

[](#installation)

```
composer require dangerwayne/laravel-specifications
```

The package will automatically register its service provider.

Artisan Command
---------------

[](#artisan-command)

Generate specification classes effortlessly using the artisan command:

```
php artisan make:specification UserActiveSpecification
```

### Command Options

[](#command-options)

#### Domain Organization

[](#domain-organization)

Organize specifications by domain or module:

```
php artisan make:specification Bookmark/SearchSpecification
php artisan make:specification Order/HighValueOrderSpecification
```

#### Model Binding

[](#model-binding)

Generate specifications bound to specific models:

```
php artisan make:specification UserPremiumSpecification --model=User
```

#### Advanced Options

[](#advanced-options)

```
# Composite specification with example composition
php artisan make:specification ComplexFilterSpecification --composite

# Include caching support
php artisan make:specification ExpensiveSpecification --cacheable

# Use builder pattern for complex rules
php artisan make:specification AdvancedRulesSpecification --builder

# Generate with test file
php artisan make:specification TestedSpecification --test

# Generate with Pest test
php artisan make:specification PestSpecification --pest

# Force overwrite existing file
php artisan make:specification ExistingSpecification --force
```

#### Combined Options

[](#combined-options)

```
# Model-bound specification with caching and test
php artisan make:specification Order/PremiumOrderSpecification --model=Order --cacheable --test

# Composite specification with builder pattern
php artisan make:specification Product/ComplexSearchSpecification --composite --builder
```

### Publishing Stubs

[](#publishing-stubs)

Customize the generated specifications by publishing the stubs:

```
php artisan vendor:publish --tag=specification-stubs
```

The stubs will be published to `resources/stubs/specification/` where you can modify them to match your coding style and requirements.

Basic Usage
-----------

[](#basic-usage)

### Using Pre-built Specifications

[](#using-pre-built-specifications)

```
use DangerWayne\Specification\Specifications\Common\WhereSpecification;

$activeUsers = User::query()
    ->whereSpecification(new WhereSpecification('status', 'active'))
    ->get();
```

### Creating Custom Specifications

[](#creating-custom-specifications)

```
use DangerWayne\Specification\Specifications\AbstractSpecification;
use Illuminate\Database\Eloquent\Builder;

class PremiumUserSpecification extends AbstractSpecification
{
    public function isSatisfiedBy(mixed $candidate): bool
    {
        return $candidate->subscription === 'premium';
    }

    public function toQuery(Builder $query): Builder
    {
        return $query->where('subscription', 'premium');
    }
}
```

### Using the Fluent Builder

[](#using-the-fluent-builder)

```
use DangerWayne\Specification\Facades\Specification;

$spec = Specification::create()
    ->where('status', 'active')
    ->where('age', '>=', 18)
    ->whereNotNull('email_verified_at')
    ->build();

$users = User::whereSpecification($spec)->get();
```

### Combining Specifications

[](#combining-specifications)

```
$activeSpec = new WhereSpecification('status', '=', 'active');
$premiumSpec = new PremiumUserSpecification();

// AND combination
$activePremiumSpec = $activeSpec->and($premiumSpec);

// OR combination
$activeOrPremiumSpec = $activeSpec->or($premiumSpec);

// NOT combination
$notActiveSpec = $activeSpec->not();
```

### Working with Collections

[](#working-with-collections)

```
$users = collect([
    new User(['status' => 'active', 'age' => 25]),
    new User(['status' => 'inactive', 'age' => 30]),
    new User(['status' => 'active', 'age' => 17]),
]);

$spec = Specification::create()
    ->where('status', 'active')
    ->where('age', '>=', 18)
    ->build();

$filteredUsers = $users->whereSpecification($spec);
```

Available Specifications
------------------------

[](#available-specifications)

The package includes several pre-built specifications:

### WhereSpecification

[](#wherespecification)

```
new WhereSpecification('status', '=', 'active');
new WhereSpecification('age', '>', 18);
new WhereSpecification('name', 'like', '%john%');
```

### WhereInSpecification

[](#whereinspecification)

```
new WhereInSpecification('status', ['active', 'pending']);
```

### WhereBetweenSpecification

[](#wherebetweenspecification)

```
new WhereBetweenSpecification('age', 18, 65);
```

### WhereNullSpecification

[](#wherenullspecification)

```
new WhereNullSpecification('email_verified_at');
```

### WhereHasSpecification

[](#wherehasspecification)

```
new WhereHasSpecification('posts', new WhereSpecification('published', true));
```

Fluent Builder Methods
----------------------

[](#fluent-builder-methods)

```
Specification::create()
    ->where('field', 'operator', 'value')    // Basic where clause
    ->where('field', 'value')                // Defaults to '=' operator
    ->whereIn('field', [1, 2, 3])           // WHERE IN clause
    ->whereBetween('field', 1, 10)          // BETWEEN clause
    ->whereNull('field')                     // IS NULL clause
    ->whereNotNull('field')                  // IS NOT NULL clause
    ->whereHas('relation', $specification)   // Has relationship
    ->or()                                   // Next condition uses OR
    ->build();                              // Build the specification
```

Configuration
-------------

[](#configuration)

Publish the configuration file:

```
php artisan vendor:publish --tag=specification-config
```

```
return [
    'cache' => [
        'enabled' => env('SPECIFICATION_CACHE_ENABLED', false),
        'ttl' => env('SPECIFICATION_CACHE_TTL', 3600),
        'prefix' => env('SPECIFICATION_CACHE_PREFIX', 'spec_'),
    ],
    'performance' => [
        'lazy_collections' => env('SPECIFICATION_USE_LAZY', true),
        'chunk_size' => env('SPECIFICATION_CHUNK_SIZE', 1000),
    ],
];
```

Advanced Usage
--------------

[](#advanced-usage)

### Custom Specifications with Parameters

[](#custom-specifications-with-parameters)

```
class AgeRangeSpecification extends AbstractSpecification
{
    public function __construct(
        private int $minAge,
        private int $maxAge
    ) {}

    public function isSatisfiedBy(mixed $candidate): bool
    {
        return $candidate->age >= $this->minAge
            && $candidate->age maxAge;
    }

    public function toQuery(Builder $query): Builder
    {
        return $query->whereBetween('age', [$this->minAge, $this->maxAge]);
    }

    protected function getParameters(): array
    {
        return [
            'minAge' => $this->minAge,
            'maxAge' => $this->maxAge,
        ];
    }
}
```

### Complex Specifications

[](#complex-specifications)

```
$specification = Specification::create()
    ->where('status', 'active')
    ->where(function ($builder) {
        return $builder
            ->where('role', 'admin')
            ->or()
            ->where('role', 'moderator');
    })
    ->whereNotNull('email_verified_at')
    ->build();
```

Testing
-------

[](#testing)

```
composer test
```

Code Quality
------------

[](#code-quality)

```
composer analyse    # PHPStan analysis
composer format     # Code formatting with Pint
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Feedback &amp; Support
----------------------

[](#feedback--support)

We'd love to hear from you! Here are ways to provide feedback or get help:

- 🐛 **Report Issues**: [Create an issue](https://github.com/dangerwayne/laravel-specifications/issues/new/choose) for bug reports
- 💡 **Request Features**: [Suggest new features](https://github.com/dangerwayne/laravel-specifications/issues/new?template=feature_request.md)
- 💬 **Ask Questions**: [Start a discussion](https://github.com/dangerwayne/laravel-specifications/discussions) or [ask a question](https://github.com/dangerwayne/laravel-specifications/issues/new?template=question.md)
- 📧 **Email**: For private inquiries, reach out to the maintainers

Contributing
------------

[](#contributing)

We welcome contributions! Please see [CONTRIBUTING](CONTRIBUTING.md) for details on:

- How to report issues
- How to suggest features
- How to submit pull requests
- Development setup and standards

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Barry Stovall](https://github.com/bstovall)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

38

—

LowBetter than 85% of packages

Maintenance63

Regular maintenance activity

Popularity33

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~8 days

Total

6

Last Release

228d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/8597531e27982ddd4caf0740d107b0e4f2cb3b509ac0a4dfea073a5d5ce0ac09?d=identicon)[dangerwayne](/maintainers/dangerwayne)

---

Top Contributors

[![bstovall](https://avatars.githubusercontent.com/u/1836574?v=4)](https://github.com/bstovall "bstovall (34 commits)")

---

Tags

laravelspecificationDomain Driven Designdddpatternbusiness-rules

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/dangerwayne-laravel-specifications/health.svg)

```
[![Health](https://phpackages.com/badges/dangerwayne-laravel-specifications/health.svg)](https://phpackages.com/packages/dangerwayne-laravel-specifications)
```

###  Alternatives

[nwidart/laravel-broadway

A Laravel adapter for the Broadway ES/CQRS package.

12315.0k](/packages/nwidart-laravel-broadway)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)[api-platform/laravel

API Platform support for Laravel

59126.4k6](/packages/api-platform-laravel)[alajusticia/laravel-logins

Session management in Laravel apps, user notifications on new access, support for multiple separate remember tokens, IP geolocation, User-Agent parser

2011.0k](/packages/alajusticia-laravel-logins)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
