joggapp/laravel-mail-viewer
Laravel Mail Viewer lets you browse, preview, and resend every email your Laravel app sends. It stores outgoing mail in the database so you can inspect rendered HTML, plain text, recipients, and attachments from a simple web UI, making debugging and testing transactional emails much easier.
This assessment is based on the v7.0.0 release notes only; version-specific API details should be confirmed against the package README and UPGRADING.md before rollout.
Install
composer require vendor/package:^7.0
v7.0.0 requires Laravel 8.x and no longer supports Laravel 6 or PHPUnit 8. Verify your host app first:
php artisan --version # expect 8.x
php -v # Laravel 8 targets PHP 7.3–8.1
composer show phpunit/phpunit
If you are on Laravel 6, stay on the 6.x line of this package — do not attempt a partial upgrade. If you are on Laravel 7, check the constraint in composer.json of the package; the notes only mention adding 8.x, so 7.x support is unconfirmed and should be assumed dropped unless the constraint says otherwise.
Where to look first
composer.json of the package — the require and require-dev blocks tell you the real Laravel/PHP/PHPUnit envelope, and extra.laravel.providers / extra.laravel.aliases tell you whether discovery is automatic.CHANGELOG.md and UPGRADING.md — the jump to a major version almost always carries config key renames, namespace moves, or signature changes not summarised in the release notes.config/*.php in the package — publish it and diff against any config you have already published.tests/ — the package's own test suite encodes the intended usage more reliably than prose docs.First use case
Do a single end-to-end smoke test in a throwaway Laravel 8 app before touching your main application:
laravel new pkg-sandbox && cd pkg-sandbox
composer require vendor/package:^7.0
php artisan vendor:publish --provider="Vendor\Package\PackageServiceProvider"
Then exercise the package's primary entry point once (a facade call, an artisan command, or a queued job — whichever the README leads with) and confirm output. This isolates "does it install and boot on Laravel 8" from "does my application's configuration still work," which are two different failure modes.
Config-first integration. Publish the config file and commit it. In Laravel 8, config caching is common in production, so any runtime config() mutation in a service provider will silently not apply after php artisan config:cache. Read config in your own service providers, not at boot in a way that depends on env vars read directly.
Prefer constructor injection over facades. Facades resolve fine, but in a package crossing a major version, the underlying binding name or class namespace is exactly what tends to move. Type-hinting the contract or concrete class surfaces a breakage at container-resolution time with a clear error, rather than at a static call site.
Wrap the package behind a thin application-level adapter. For anything used in more than a couple of places, define your own small service or repository that delegates to the package. This is the cheapest insurance against the next major bump and makes the package swappable if Laravel 8 support ages out.
Testing pattern. Laravel 8 pairs with PHPUnit 9, and the package's own require-dev will reflect that. In your application tests:
phpunit.xml schema if you are coming from PHPUnit 8 (the <coverage> block moved under <coverage> with <include>/<exclude> children).Database\Factories\UserFactory) rather than the $factory->define() global closure style. Any package test helper or trait that assumed the old style will need adjusting.orchestra/testbench:^6.0 for Laravel 8.Queue and event integration. If the package dispatches jobs or events, register listeners in a dedicated EventServiceProvider entry and assert on them with Event::fake() in tests. Major versions frequently rename event classes or change payload shapes — asserting on the payload, not just the class, catches this.
Upgrade workflow from v6. Branch, bump the constraint, run composer update vendor/package --with-dependencies, then immediately run the full test suite plus a manual pass over the package's artisan commands. Do not batch this with other dependency upgrades; if something breaks, you want a single suspect.
composer.json pins phpunit/phpunit:^8, the solver will fail or composer update will refuse. Bump to ^9.5 and convert setUp()/tearDown() signatures to include : void if they do not already — PHPUnit 9 enforces this and it is the most common silent breakage.config/app.php with manual provider entries from a Laravel 6/7 era, you can end up with the provider registered twice, producing duplicate route or event registration. Remove the manual entry when discovery is present.php artisan config:clear && php artisan cache:clear && composer dump-autoload before debugging anything. A large share of "the package is broken" reports after a major bump are stale caches or a stale autoloader.RouteServiceProvider. If the package registers routes with string controller actions like 'PackageController@index', confirm they still resolve under the new convention.composer show vendor/package after install; a constraint of ^7.0 on a dependency you did not directly require can resolve to an older 7.x than you expect.extend-style hooks are common in this ecosystem and are usually more upgrade-stable than subclassing internals.composer.lock and upgrade the package deliberately rather than letting CI float it.How can I help you explore Laravel packages today?