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

Contracts Laravel Package

orchestra/contracts

Orchestra Contracts provides the shared interfaces and abstractions that underpin the Orchestra Platform for Laravel. It keeps packages loosely coupled and consistent, making Orchestra-based applications easier to build, extend, and maintain.

View on GitHub
Deep Wiki
Context7

Getting Started

orchestra/contracts is an interfaces-only package — no service provider, no config file, no routes, no migrations. "Getting started" means confirming you belong in the Orchestra graph and then reading PHP interfaces, not docs.

  1. Confirm the dependency is justified. Run composer why-not orchestra/contracts against your target Laravel version. This single command is the fastest go/no-go. If you're not already on orchestra/foundation or orchestra/testbench, stop — Illuminate\Contracts\* plus PSR is the lower-risk default.
  2. Install at a pinned major that tracks your Laravel version (branches follow Laravel majors; v7 tracks Laravel 9):
    composer require orchestra/contracts:^7.0
    
  3. Read src/ first — it is the documentation. The repo contains interface definitions for extension discovery, application access, shared memory, authorization bridging, notifier, and widget abstractions. There is no narrative doc worth reading before the interfaces themselves.
  4. Then read the implementations in orchestra/foundation and siblings. The contracts are not self-documenting; their semantics live in the concrete classes that satisfy them.

First real use case: you're shipping a package into the Orchestra ecosystem and want to type-hint Orchestra\Contracts\... instead of depending on the full platform, keeping your classes swappable and testable. Second: you're building an adapter layer and want a pre-built, Laravel-native vocabulary instead of inventing your own ports.

Implementation Patterns

Type-hint the contract, resolve the implementation. Standard Laravel container pattern — the value is that consumers never name a concrete Orchestra class:

use Orchestra\Contracts\Extension\Factory as ExtensionFactory;

class MyPackageServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(MyAggregator::class, function ($app) {
            return new MyAggregator($app->make(ExtensionFactory::class));
        });
    }
}

Adapter-first, dependency-second. The workflow that keeps the seam honest:

  1. Define your own application-facing port for the concern you need (extension registry, authorization, notifications).
  2. Write two adapters — one against Orchestra (implementing the Orchestra contract), one against your current code.
  3. Only once the seam is proven, bind the Orchestra interface as the adapter's contract and take the Composer dependency.

A future re-platform of the admin layer then touches adapters, not feature modules.

Implement the Orchestra interface directly when your package is the extension point (custom extension driver, widget, notifier). Keep the implementing class thin and delegate to domain services:

use Orchestra\Contracts\Extension\Factory;

class MyExtensionFactory implements Factory
{
    public function __construct(private ExtensionRegistry $registry) {}
    // delegate every method to $this->registry
}

Fake it in tests. Because these are interfaces, bind a fake in the container for unit tests and skip the whole platform:

$this->app->instance(
    \Orchestra\Contracts\Extension\Factory::class,
    new class implements \Orchestra\Contracts\Extension\Factory { /* ... */ }
);

Or, if you're on Orchestra Testbench, let it provide real bindings and assert against behaviour instead.

Guard against signature drift with a conformance test. Add a test that simply asserts your adapter implements the interface and that signatures line up — a minor upstream interface change then fails in CI with a clear message instead of a fatal type error at boot:

public function test_adapter_implements_orchestra_contract(): void
{
    $this->assertInstanceOf(\Orchestra\Contracts\Extension\Factory::class, new MyExtensionFactory(...));
}

Centralize the pin. If more than one service consumes the contracts, publish a shared internal package or a Composer platform constraint so one upstream major bump doesn't fan out into N coordinated upgrades.

Fork path for teams that want only the vocabulary. The interfaces are small, MIT-licensed, and stable in shape. Forking them into App\Contracts is a legitimate pattern — it removes upgrade-gating risk at the cost of maintaining a few hundred lines in-house. Decide this before you need it.

Gotchas and Tips

  • It does nothing on its own. Zero runtime behaviour means zero standalone value. If you're evaluating it in isolation, you're evaluating the wrong thing — the real question is whether you're adopting Orchestra.
  • illuminate type-hints negate portability. The interfaces reference Illuminate\Contracts\Foundation\Application, Illuminate\Support\Collection, and so on. If your goal was framework-agnostic ports, this package doesn't deliver it — a hand-written narrow interface set is a cleaner boundary.
  • Version branches are your upgrade calendar. Each Orchestra major tracks a Laravel major. The most likely real-world failure isn't a bug — it's a Laravel upgrade blocked waiting on an upstream tag. Budget ~an engineer-hour per Laravel major plus the wait you don't control.
  • composer why-not is the whole go/no-go. Run it against your target Laravel version before planning any work. Make it a CI pre-merge check to catch illuminate range collisions early.
  • Watch for transitive Orchestra. If a dependency already pulls Orchestra in, you're managing this pin regardless — audit before you decide.
  • Signature drift is silent until boot. The contracts ship no published BC policy or signature-assertion suite. A "minor" interface change surfaces as a fatal type error in your implementing classes. Your own conformance test is the mitigation.
  • Don't put it on a critical path. Single maintainer, effectively zero external dependents, no SLA. Treat "no response upstream" as the default assumption and keep it off any capability whose release it could block.
  • Fork feasibility is your safety valve — verify it now. Confirm the license and file count up front, and write the fork procedure into the runbook before you need it under pressure. MIT plus a small interface set makes this cheap; deciding reactively makes it expensive.
  • Allocate reading time for semantics, not syntax. Ramp-up is an afternoon for anyone fluent in Laravel contracts and container binding — the hidden cost is understanding Orchestra's extension, memory, and widget semantics, which requires reading the implementation packages, not this repo.
  • Pin deliberately and name an owner. Someone must be accountable for mapping upstream releases onto your framework upgrade calendar. Without a named owner, the upgrade block happens to you rather than being planned for.
  • Extension points worth knowing: container binding overrides, your own adapter implementations, and vendored forks under your own namespace. These are the levers; the package itself offers no hooks, providers, or config to extend.
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.
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
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core