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 Beyond Laravel Package

regnerisch/laravel-beyond

Laravel Beyond adds Artisan generators and base classes for action-oriented Laravel apps, including Actions, Data Transfer Objects, and View Models. It helps organize domain logic and move beyond traditional CRUD structure.

View on GitHub
Deep Wiki
Context7

Getting Started

Version note (v7.1.0): This release drops Laravel 10.x support and adds Laravel 12.x support. The package now targets Laravel 11.x and 12.x only. If you're still on Laravel 10, stay on the 7.0.x line or plan your framework upgrade first.

Install

composer require <vendor>/laravel-adr:^7.1
php artisan vendor:publish --tag=adr-config

Confirm your composer.json platform requirement is laravel/framework: ^11.0|^12.0 before upgrading — Composer will otherwise resolve you back to 7.0.x without warning.

Where to look first

  1. config/adr.php — namespace roots and paths for Actions, Domains, and Responders. This is the first thing to align with your team's conventions (App\Actions vs App\Domain\...\Actions).
  2. The generated stub files (php artisan vendor:publish --tag=adr-stubs) — these define what a generated class looks like on day one.
  3. php artisan list beyond — confirms the available generators for your installed version.

First use case

The flagship addition in 7.1.0 is the action generator. Scaffold your first vertical slice:

php artisan beyond:make:adr-action CreateOrderAction

Then wire it into a controller as an invokable dependency:

final class OrderController extends Controller
{
    public function __construct(private CreateOrderAction $action) {}

    public function store(CreateOrderRequest $request): JsonResponse
    {
        $order = ($this->action)($request->validated());

        return (new OrderResponder($order))->toResponse($request);
    }
}

That's the whole loop: request → action → domain → responder. Start with one endpoint, not a full refactor.

Implementation Patterns

One action per use case. Actions are invokable classes that take primitives/DTOs and return a result object or model. Keep them container-resolvable (constructor injection only) so Laravel can resolve them and so you can swap them in tests.

final class CreateOrderAction
{
    public function __construct(
        private OrderRepository $orders,
        private PaymentGateway $payments,
    ) {}

    public function __invoke(CreateData $data): Order
    {
        return DB::transaction(function () use ($data) {
            $order = $this->orders->create($data);

            $this->payments->charge($order, $data->paymentToken);

            return $order;
        });
    }
}

Responders handle the "what do we send back". Keep the responder unaware of the action and vice-versa. This is the part that pays off when you add an API alongside an existing web flow:

final class OrderResponder
{
    public function __construct(private Order $order) {}

    public function toResponse(Request $request): JsonResponse|Response
    {
        return $request->expectsJson()
            ? new JsonResponse(new OrderResource($this->order), 201)
            : response()->view('orders.show', ['order' => $this->order]);
    }
}

Workflow tips that actually get used

  • Generators are the interface. Standardise on beyond:make:adr-action for every new use case; it's the fastest way to keep the folder structure consistent across the team. Publish and edit stubs (vendor:publish --tag=adr-stubs) once, so every generated action has final class, readonly promoted properties, and your docblock conventions baked in.
  • Queue off the action, not the controller. Wrap the action in a job that mirrors its signature; the action itself never calls dispatch() — that keeps it testable and transport-agnostic.
  • Test actions without HTTP. A feature test hitting the route plus a unit test invoking the action directly covers both wiring and logic:
it('creates an order', function () {
    $order = app(CreateOrderAction)(new CreateData(...));

    expect($order)->toBeInstanceOf(Order::class);
});
  • Bind contracts in a service provider. If your actions depend on interfaces, register them in AppServiceProvider — actions resolved from the container will pick them up automatically, and you get free mocking in tests via $this->mock(PaymentGateway::class).
  • Form Requests stay at the edge. Do validation in the Form Request, then pass ->validated() into the action. Don't let actions take Request instances — it's the most common way to leak HTTP concerns into your domain layer.
  • Namespace collision check on multi-package projects. The beyond: command prefix is shared with other Beyond Code packages; run php artisan list after install to confirm you're seeing the generators you expect, not a namespace clash.

Gotchas and Tips

Framework version is the new tripwire. Dropping Laravel 10 is a hard break:

  • composer update on an L10 app will silently keep you on 7.0.x — check composer show <vendor>/laravel-adr after upgrading and don't assume you got 7.1.
  • If you pin laravel/framework: ^10|^11, the constraint resolution will fight you. Upgrade the framework first, then the package, not the other way around.
  • Any Laravel 11-only APIs you were relying on are now safe to use — the package no longer ships a compatibility layer for L10, so behaviour on 10 is unsupported.

Autoload traps. Generated classes land in the namespaces defined in config/adr.php. If you change that config after generating files, you'll get "class not found" errors that look like a package bug. Fix:

php artisan config:clear
composer dump-autoload

Stubs are copied, not inherited. Once you publish stubs, they're yours — package upgrades will not update them. Re-publish to a temp tag or diff against vendor/.../stubs/ after upgrading to 7.1 so your generators pick up any formatting or signature changes.

Config caching. In production (php artisan config:cache), changes to config/adr.php are ignored until you re-cache. Generators run in dev, so this bites mainly when the config defines runtime bindings or paths used by service providers — clear the cache as part of deploy.

Debugging generators. Most "nothing happened" reports are one of:

  • Running without -v and missing the "file already exists" skip.
  • The target directory isn't writable (Docker volume mounts are a classic).
  • Your App\ PSR-4 root points somewhere the config doesn't.

php artisan beyond:make:adr-action Foo -v tells you the resolved path before writing.

Extension points to lean on

  • Stub overrides — the cheapest customisation; no package forks.
  • Container bindings — bind action interfaces in a provider to swap implementations per environment (e.g. a fake payment gateway in staging).
  • Custom responder contract — if you need a consistent response envelope across the app, implement a Responder contract and generate against it rather than editing each class.
  • Config-driven paths — in monorepos or modular apps, point the namespace roots at Modules\Sales\Actions etc. rather than patching the generator.

One last thing for 7.1 adopters: the new adr-action command is additive, so existing projects upgrading from 7.0.x need no migration work beyond the framework bump. The only real cost of this release is the Laravel 10 boundary — plan that as a separate PR from any feature work so a rollback is trivial.

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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core