Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Arkitect Laravel Package

mortexa/laravel-arkitect

Laravel Arkitect helps you define and enforce architecture rules in Laravel applications. Describe layer dependencies, naming and structural conventions with an expressive API, then catch violations in tests or CI before they spread.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package as a dev dependency and publish its config:

composer require --dev mortexa/laravel-arkitect
php artisan vendor:publish --tag="arkitect-config"

The config file (config/arkitect.php) tells the package where architectural tests live. By default, the package scans tests/Architecture for classes extending the package's base test case.

Create your first architectural test:

<?php

namespace Tests\Architecture;

use Mortexa\LaravelArkitect\Testing\Test;

class ControllersTest extends Test
{
    public function test_controllers_follow_convention(): void
    {
        $this->rules()
            ->classes()
            ->that()
            ->liveIn('App\Http\Controllers')
            ->should()
            ->haveSuffix('Controller')
            ->beFinal()
            ->because('the team agreed on this convention');
    }
}

Run it like any PHPUnit/Pest test — vendor/bin/phpunit tests/Architecture — or via the package’s artisan command (usually php artisan arkitect). First use case: codifying the naming/namespace rules your team already argues about in code review, so they become red builds instead of PR comments.

Start by looking at the README (it has the full rule catalogue and example tests) and the Mortexa\LaravelArkitect\Testing\Test class, which exposes $this->rules() and Laravel-specific helpers. Also inspect the published config to know where it looks for tests and which paths it lints — that’s the file you’ll edit most often when onboarding a team.

Implementation Patterns

One test class per layer or bounded context. Keep ControllersTest, ModelsTest, JobsTest, DomainTest separate. Each rule set is a normal test — failing rules point at the specific file and line, so granular grouping makes reports actionable.

Convention-first, not correctness-first. Arkitect is for rules a linter or static analyser can’t express cheaply: "controllers must not depend on models directly", "jobs must implement ShouldQueue", "all classes under App\Domain\* must be final", "FormRequests must live in App\Http\Requests". Use it to enforce agreements, not to replace PHPStan.

Dependency-direction rules are the killer feature. For example, to protect a hexagonal layout:

$this->rules()
    ->classes()
    ->that()
    ->liveIn('App\Domain')
    ->should()
    ->not()
    ->dependOn('App\Http', 'App\Jobs', 'App\Console')
    ->because('the domain stays framework-agnostic');

Laravel-aware helpers. The package adds conveniences over base PHPArkitect — checks for beInvokable(), extending Illuminate\* base classes, implementing contracts like ShouldQueue, and living in App\Http\Controllers / App\Http\Requests. Prefer these over hand-rolled string checks; they understand namespaces and inheritance.

Rule reuse via base test classes or traits. Teams usually grow a Tests\Architecture\ArchTestCase that pre-defines shared rules (final classes, no dd()/dump(), no env() outside config). New projects extend it and add project-specific rules.

CI integration. Add vendor/bin/phpunit tests/Architecture --testsuite=Architecture (or a dedicated test suite in phpunit.xml) to your pipeline. Because rules are plain PHPUnit/Pest tests, they inherit your existing parallel execution, coverage exclusion, and reporting — no separate tooling to wire up.

Pest users can wrap rules in uses(Test::class) or invoke the package test case inside it() blocks. The package doesn’t fight Pest; it’s just another PHPUnit test class.

Combining with a because() chain. Always attach ->because(...) to non-obvious rules. When a rule fails six months later, the message becomes the design decision, not just a rule name.

Gotchas and Tips

  • Autoloading and path assumptions. Rules resolve classes by namespace. If you rename App\Domain\Foo to App\Domain\Bars\Foo, rules targeting the old namespace silently pass. Keep path rules (liveIn) and class rules (extend, implement) in sync — path-based filters are the safer default.
  • should()->not()->... chains aren’t free. Complex negations across many classes can be slow. Filter first with that()->liveIn(...), then assert.
  • Interfaces and abstract classes. extend() matches direct inheritance unless you use the "implement" or "recursive implements" methods — read the rule catalogue so you don't accidentally require beFinal() on abstract base classes. Combine with that()->areNotAbstract() when needed.
  • Config caching. php artisan config:cache in CI or deployment pipelines can hide newly published arkitect.php changes. Clear the cache before running architecture tests in your pipeline.
  • Vendor and generated code. Exclude vendor/, bootstrap/cache/, generated stubs, and IDE helpers in the config exclude list. Scanning them slows the suite and produces noisy failures for code you don’t own.
  • False positives from facades and traits. belongsTo and dependency checks operate on declared types; traits and facade calls are not always visible. If a false positive appears, inspect the resolved class name using --filter on a single test and add a temporary dd() on the rule builder’s target list.
  • Version pinning and PHPArkitect compatibility. As of v0.8.1, this package supports phparkitect/phparkitect ^0.3.19 | ^0.4.0 | ^0.5.0, so you have more headroom to stay current with the underlying engine. Still, avoid pinning phparkitect/phparkitect directly without an intentional constraint — Composer may resolve a version outside the supported range (e.g. 0.3.x below 0.3.19, or a future 0.6+) and rules can behave differently. If rules start misbehaving after a composer update, check composer.lock for both packages and bump them together.
  • Escape hatch — not a replacement for review. Rules that require deep runtime context (config resolution, container bindings, query behaviour) belong in feature tests, not Arkitect. Over-reach leads to brittle suites people disable.
  • Debugging: run a failing rule with --filter to isolate it, inspect the reported file/line, and confirm with a one-off dd($this->rules()->getClasses()) style check on the builder if available. Most “weird” failures are stale autoload (composer dump-autoload) or a class file that doesn’t match its namespace.
  • Extension points. If a check you need isn’t built in, Arkitect’s rule system allows custom rules; the package’s Test base class exposes the underlying rule builder, so you can drop down to raw PHPArkitect rules when needed. Keep custom rules in a dedicated namespace (Tests\Architecture\Rules) so they’re discoverable.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource