weiwait/nova-image
A Laravel Nova field package by weiwait for handling images in admin panels. Add image upload, preview, and management to Nova resources with a lightweight, drop-in field that keeps form configuration simple and familiar for Laravel developers building resource forms.
1.0.0 is the initial release, so there is no upgrade path or deprecation surface to worry about — but it also means the public API is at its least proven. Treat the first integration as a spike, not a commitment.
Install and confirm discovery
composer require <vendor>/<package>:^1.0
php artisan about # confirms the provider registered
php artisan vendor:publish --provider="<Vendor>\<Package>\<Package>ServiceProvider"
Look at these in order before writing any application code:
composer.json — PHP and Laravel version constraints, plus extra.laravel.providers / aliases. If the provider isn't auto-discovered, you'll be registering it manually in bootstrap/providers.php.register() and boot() — this is where config merging, singletons, and publishing tags are declared. It tells you more about the package's real shape than the README does.config/ file after publishing — every knob the author intended you to touch.First use case: reach for the package on a single, low-risk code path — one controller, one job, one Artisan command — rather than threading it through your domain layer. If it's a data-access or integration package, point it at a throwaway or staging connection first and confirm behaviour before it touches production data.
Resolve from the container, don't instantiate. If the provider binds a singleton or interface, inject it through the constructor and let Laravel resolve it. Hard-coding new PackageClient(...) bypasses config merging and makes tests painful.
final class SyncOrders
{
public function __construct(private readonly PackageContract $package) {}
public function __invoke(): void { /* ... */ }
}
Bind the contract in a service provider if the package ships an interface. That gives you a one-line swap for a fake in tests and a seam for wrapping the package behind your own adapter — worth doing on day one for anything that talks to a third party.
$this->app->bind(PackageContract::class, fn ($app) => $app->make(PackageClient::class));
Wrap it in your own thin adapter if the surface is broad. A single App\Support\... class that exposes only the three or four methods you actually call means a 1.x → 2.x breaking change lands in one file instead of forty. This is cheap insurance on any package still in its first major version.
Drive it from queues and commands, not request cycles. Long-running calls belong in a job with $tries/$backoff set explicitly, or behind a scheduled command. This also isolates failures from user-facing latency while you learn the package's behaviour.
Config over code. Anything the package exposes in config/ should be set via env() in your .env and referenced in the config file, not mutated at runtime with config()->set(). Cache the config (php artisan config:cache) and re-test — a surprising number of packages read env vars directly and break under caching.
Test with fakes at the boundary. Use Http::fake() for HTTP-backed packages, Queue::fake()/Bus::fake() for dispatch-driven ones, and RefreshDatabase if it ships migrations. Assert on your adapter's output, not on the package's internals — internal assertions turn every patch release into a test rewrite.
vendor:publish --force overwrites your edits. Publish once, commit the config, and diff against the vendor copy when you upgrade.--tag. Duplicate table creation on a fresh DB is the classic first-run failure.config:cache combined with a package that calls env() outside a config file. That's the author's bug, but it's your outage.^1.0 on a first release means you'll absorb every 1.x patch. Pin tighter (1.0.*) for anything on a critical path until the package has a few releases behind it. Watch for caret ranges that allow a Laravel major you don't run yet.@see/@method annotations.php artisan tinker to poke at the resolved instance, php artisan about to confirm registration, and Log::debug() inside a wrapper rather than inside vendor code so your instrumentation survives composer update.git diff on the config/ directory and the service provider between tags — that's where breaking changes hide.How can I help you explore Laravel packages today?