genealabs/laravel-tenancy-scout
Integrates Laravel Scout with GeneaLabs Laravel Tenancy to make search indexing and querying tenant-aware. Keep Scout models, indexes, and results scoped to the current tenant so each tenant searches only its own records in multi-tenant Laravel apps.
This release's headline change is Laravel 11 support, so the first job is confirming the package actually resolves on your framework version before you build anything on top of it.
Check the constraint before installing. Open the package's composer.json on the tag you intend to use and confirm the illuminate/* requirement reads something like ^10.0|^11.0. A release note saying "Laravel 11 compatibility" is a claim; the constraint is the contract. If it still reads ^10.0, the compatibility is partial.
Install and let discovery do its job.
composer require vendor/package:^0.4.0
Most Laravel packages register a service provider via extra.laravel.providers. Verify it landed with php artisan about or by checking bootstrap/cache/packages.php after a composer dump-autoload.
Look at these files first, in order: README.md → config/*.php (if publishable) → the service provider's register()/boot() → CHANGELOG.md. The service provider tells you what's bound into the container and under what keys, which is what you'll actually be resolving day-to-day.
Publish config only if you need to change a default.
php artisan vendor:publish --tag=package-config
Then diff the published file against the package's own copy to see which keys are genuinely meant to be touched.
First use case: wire the package into a single, disposable surface — one route closure or one throwaway Artisan command — and confirm end-to-end behaviour before touching production code paths. If the package ships a facade, resolve it from the container rather than instantiating anything directly, so you find out immediately whether autowiring is set up correctly.
Because this is a 0.x release, treat the public API as unstable. Pin the version in composer.json rather than floating on ^0.4.
Resolve through the container, never with new. Laravel packages almost always bind an interface or a configured singleton. Constructor-inject it into controllers, jobs, and commands:
public function __construct(private PackageContract $service) {}
This is also what makes the package swappable in tests.
Keep configuration in config/ and environment in .env. Bind package config values to env vars in your own config/services.php or a dedicated config file, then reference them with config(). Avoid reading env() outside config files — it returns null once config:cache has run.
Isolate the package behind a thin wrapper. For anything you'll call from more than two places, write a small application-level service that wraps the package. When 0.5.0 renames a method, you change one file instead of forty. This is cheap insurance on a pre-1.0 dependency.
Compose in a dedicated service provider when you need to rebind, decorate, or swap the package's implementation:
public function register(): void
{
$this->app->extend(PackageContract::class, fn ($concrete, $app) => new Decorated($concrete));
}
Queued jobs need care. If you pass the package's objects into a job constructor, they must be serializable. Prefer passing scalar IDs and re-resolving the service inside handle(), which also avoids stale state on long-running workers.
Pair it with the framework's own primitives rather than working around them: use the package inside a Route::middleware() group, a scheduled command, or an event listener, so the existing Laravel error handling, logging, and retry semantics still apply.
Test at the seam. If the package ships fakes or an in-memory driver, register it in TestCase::setUp(). Otherwise bind a mock of the contract in the container for feature tests and keep one real integration test that exercises the actual package against a test database.
Laravel 11 changed the application skeleton, and this is where "compatibility" usually bites. Laravel 11 removed app/Http/Kernel.php and app/Console/Kernel.php in favour of bootstrap/app.php. Packages that registered middleware or commands by reaching into those kernels will silently do nothing on a fresh Laravel 11 app. If the package is meant to add middleware, confirm the README's install steps match the Laravel 11 style (->withMiddleware() in bootstrap/app.php) and not the old kernel array.
Laravel 11 requires PHP 8.2+. If your CI matrix still includes 8.1, the install will fail on the framework constraint, not on the package — a confusing error if you're not expecting it.
Clear the discovery cache after upgrading. Stale bootstrap/cache/packages.php and services.php are the single most common cause of "the package is installed but its facade is undefined." Run:
php artisan optimize:clear
Config caching hides env() calls. If the package reads environment variables directly instead of going through config, it will work in php artisan serve and break in any cached deployment. Test with php artisan config:cache locally before shipping.
Diagnose version conflicts with why-not, not by guessing:
composer why-not vendor/package 0.4.0
composer show --tree vendor/package
This tells you which other dependency is pinning illuminate/support below 11.
Watch for singleton state under Octane and queue workers. A package that stores per-request data on a singleton will leak it between requests in a long-lived worker. If the package has a flush()/reset() hook, call it from a terminating callback or job middleware.
0.x means minor versions can break. 0.4.0 → 0.5.0 is permitted to include breaking changes under semver. Read the changelog on every bump, and commit your composer.lock so upgrades are deliberate.
Extension points to check for before forking anything: a publishable config file, a bound interface you can extend(), a Macroable trait, or a driver/manager class with a extend() method. Any one of these means you can customise behaviour without patching vendor code — and vendor patches are the thing you'll regret at the next upgrade.
Debugging a binding that won't resolve: app()->bound(Key::class) and php artisan tinker are faster than reading stack traces. If the container throws Target [X] is not instantiable, the package's provider probably didn't load — go back to step 2 of Getting Started.
How can I help you explore Laravel packages today?