arielmejiadev/larapex-charts
Larapex Charts wraps ApexCharts in a clean Laravel API so you can build interactive, responsive charts from PHP or Blade with fluent methods and no JavaScript. Supports line, bar, pie, donut, radial and more, with customizable options and simple data binding.
This is a major-version release (10.0.0) whose headline change is Laravel 13 support. Treat it as an upgrade-and-verify release first, adoption second — the day-to-day ergonomics of the package are unchanged, but the floor of your dependency graph moves.
Check your constraint before anything else. A 10.x tag alongside "support Laravel 13" almost always means older framework versions were dropped. Run:
composer why-not vendor/package ^10.0
composer show vendor/package --all | head -40
If you are still on Laravel 11/12, stay on 9.x and pin it explicitly ("vendor/package": "^9.0") so a composer update cannot drag you across a major boundary.
Upgrade in a branch, not in place. composer require vendor/package:^10.0 -W then php artisan optimize:clear before booting. Config and service-provider registration are the two things that break silently on a major bump.
Where to look first:
CHANGELOG.md / UPGRADE.md — the release note you were given is one line; the changelog is the real migration guide.composer.json of the package — read the require block yourself to confirm the PHP and illuminate/* constraints.src/*ServiceProvider.php — shows what is bound in the container, what is publishable, and what is registered conditionally.config/<package>.php after publishing — the defaults are the contract.First use case to prove the upgrade: pick the single most-used code path in your app that touches this package (one controller action or one queued job), and write a feature test around it before upgrading. Green before and green after is the only signal that matters on a major bump. Do not start with the edge cases.
Resolve through the container, not the facade, in application code. Facades are convenient in views and quick scripts, but constructor-injecting the package's contract (or the concrete class if none is published) keeps your services testable and makes a future major bump a one-file change:
final class SyncOrders
{
public function __construct(private readonly PackageClient $client) {}
public function __invoke(Order $order): void
{
$this->client->push($order->toPayload());
}
}
Wrap the package behind your own thin adapter. On a package that has now crossed ten major versions, the churn is in the package, not in your domain. A single App\Support\PackageGateway that delegates to the package means framework-support releases like this one become a composer.json edit plus one adapter review, not a grep across the codebase.
Keep published config in version control, keep secrets in env. Publish once (php artisan vendor:publish --provider="Vendor\Package\PackageServiceProvider"), commit the file, and make every meaningful value read env('...') with a sane default. This is what lets you diff a major upgrade meaningfully — an unchanged config file plus a changed package is a readable diff.
Drive behaviour from config, not from calls. Most Laravel packages of this vintage expose a manager/driver pattern or a set of toggles. Prefer flipping a config key over branching in application code; it keeps the package's own extension points (custom drivers registered via extend(), macros, container bindings) available to you.
Test with the package's fakes and the real container. Use RefreshDatabase (or DatabaseTransactions) if the package publishes migrations, and use Http::fake() / Queue::fake() / Event::fake() around it rather than mocking the package's internals — internals are exactly what a major version is allowed to change. If the package ships its own fake or testing trait, wire it into TestCase::setUp() now so you get it for free on the next bump.
Queue anything that talks to the network. Wrap package calls in a job with $tries, $backoff, and a failed() handler. Package-level retry semantics are not guaranteed to survive a major release; your job's are.
Upgrade rehearsal as a pattern. Add a CI job (or a local composer script) that runs composer update --prefer-lowest on a schedule. With a package that just widened its framework ceiling, this is what surfaces the next incompatibility before a customer does.
10.0.0 is a major tag. Read the require block in the package's composer.json: dropped PHP versions, dropped illuminate/* ranges, and bumped transitive dependencies are the usual unstated payload.composer update will not cross the major for you if you were constrained to ^9.0 — and if you were constrained to * or dev-main, it will cross it silently. Audit your constraint style before and after.php artisan config:clear && php artisan optimize. A cached config.php from the previous version can mask a removed key for hours.vendor:publish --force overwrites your customisations. Instead, publish with --tag to a temp path and diff against your committed config to see which defaults changed.loadMigrationsFrom(), upgrading can try to run the same migration twice. Check migrations/ for duplicate filenames after upgrading.php artisan queue:restart after — workers hold old code in memory.Facade::clearResolvedInstances() and re-bind in tearDown().extend() with a custom driver, a Macroable trait, or a container binding you can bind()/singleton() in your own AppServiceProvider. Patching vendor code is what turns a routine framework-support bump into a multi-day merge.Log channel and error handler during the first deploy after upgrading — deprecation notices from this package will show up there first.dd(). If the package is opaque, php artisan telescope:install and watch the queries, jobs, and HTTP calls it makes on one request. That single trace usually replaces an hour of source reading.composer.lock, commit the lock, and deploy the lock. With a fresh major release, composer install on the lock file is your reproducibility guarantee; anything looser and two deploys a day apart can behave differently.How can I help you explore Laravel packages today?