Weave Code
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

Livecharts Laravel Package

matheusmarnt/livecharts

LiveCharts is a reactive chart abstraction for Laravel using a pure PHP fluent API. Build 18 chart types and render via a single Livewire component. Supports ApexCharts and Chart.js with pluggable engines, enabling easy updates without JS boilerplate.

View on GitHub
Deep Wiki
Context7

Installation Guide

Requirements

  • PHP ^8.2
  • Laravel ^10.0 || ^11.0 || ^12.0 || ^13.0
  • Livewire ^3.0 || ^4.0

Laravel 10 caveat: the package's composer.json declares ^10.0 for runtime compatibility, but the test matrix only exercises Laravel 11/12/13 because pestphp/pest-plugin-laravel ^3.0 requires Laravel 11+. Production use on Laravel 10 is supported but not CI-validated.

1. Install the package

composer require matheusmarnt/livecharts

The service provider is auto-registered via Laravel's package discovery. The LiveCharts facade is aliased automatically.

2. Run the installer

php artisan livecharts:install

The installer:

  1. Publishes config/livecharts.php
  2. Publishes the LiveCharts JS runtime and the pre-built engine bundles (livecharts.js, apexcharts.js, chartjs.js, plus Chart.js plugins for treemap, matrix, sankey, financial, luxon, adapter-luxon) to public/vendor/livecharts/js
  3. Prompts whether to publish chart class stubs to stubs/livecharts (used by make:chart)

⚠️ Assets must be published for local and both modes

The default asset mode is both (local first, CDN fallback). The files in public/vendor/livecharts/js/ must exist for this to work. If you skip livecharts:install, assets are missing after a fresh clone, or a deployment wipes public/vendor/, every chart will fail silently with ApexCharts is not defined or Chart is not defined.

Re-publish assets on demand:

php artisan vendor:publish --tag=livecharts-assets --force

Verify the output:

ls public/vendor/livecharts/js/
# Expected: apexcharts.js  chartjs.js  livecharts.js  (+ plugin bundles)

If you prefer no local files, set LIVECHARTS_ASSETS_MODE=cdn in .env — no publish step needed.

Environment-specific invocations

Environment Artisan invocation
php artisan serve (host) php artisan <command>
Laravel Sail ./vendor/bin/sail artisan <command>
Docker Compose (non-Sail) docker compose exec app php artisan <command>

3. Wire the asset directive

LiveCharts ships in both mode by default (since v2.2.0): the locally-published engine bundles are served first, with the matching jsDelivr CDN URL wired as the <script onerror> fallback.

Asset strategy

Since v2.7.7, LiveCharts uses the navigate strategy by default. Charts emit their engine scripts via Livewire's [@assets](https://github.com/assets) block — no [@liveChartsScripts](https://github.com/liveChartsScripts) directive required. This strategy works correctly with wire:navigate SPA navigation.

<!DOCTYPE html>
<html>
<head>
    [@livewireStyles](https://github.com/livewireStyles)
</head>
<body>
    {{ $slot }}
    [@livewireScripts](https://github.com/livewireScripts)
</body>
</html>

If you need to use the legacy stack strategy (e.g. for non-Livewire contexts or manual placement), set LIVECHARTS_ASSETS_STRATEGY=stack and add [@liveChartsScripts](https://github.com/liveChartsScripts) before [@livewireScripts](https://github.com/livewireScripts):

LIVECHARTS_ASSETS_STRATEGY=stack
<body>
    {{ $slot }}
    [@liveChartsScripts](https://github.com/liveChartsScripts)
    [@livewireScripts](https://github.com/livewireScripts)
</body>

wire:navigate (Livewire SPA): the navigate strategy handles SPA navigation automatically. The stack strategy does not support wire:navigate — charts on navigated pages will throw livecharts is not defined.

Asset modes: both (default — local-first with CDN fallback), local (no CDN), or cdn (no local). Switch via LIVECHARTS_ASSETS_MODE in .env or config/livecharts.php. See Local assets below.

4. Build a chart

Fluent builder

use Matheusmarnt\LiveCharts\Facades\LiveCharts;

$chart = LiveCharts::line()
    ->title('Monthly Revenue')
    ->labels(['Jan', 'Feb', 'Mar'])
    ->dataset('2026', [100, 200, 150])
    ->colors(['#3B82F6']);

Class-based chart

Generate a class:

php artisan make:chart RevenueChart --type=bar

Edit app/Charts/RevenueChart.php:

namespace App\Charts;

use Matheusmarnt\LiveCharts\Charts\Chart;
use Matheusmarnt\LiveCharts\Charts\Dataset;
use Matheusmarnt\LiveCharts\Enums\TwColor;

class RevenueChart extends Chart
{
    protected string $type = 'bar';

    public function __construct()
    {
        parent::__construct();

        $this
            ->title('Revenue')
            ->labels(['Jan', 'Feb', 'Mar'])
            ->datasets([
                Dataset::make('2026')
                    ->data([400, 300, 600])
                    ->backgroundColor(dark: TwColor::Emerald400, light: TwColor::Emerald600),
            ]);
    }
}

Available --type values: line, bar, area, pie, donut, radar, scatter, bubble, heatmap, rangeBar, radialBar, polarArea, boxPlot, treemap, candlestick, matrix, sankey.

Stubs: if you accepted the stubs prompt during livecharts:install, the generator stub lives at stubs/livecharts/chart.php.stub. Edit that file to customize the boilerplate emitted by make:chart.

5. Render the chart

<livewire:livecharts :chart="$chart" />

For a class-based chart:

<livewire:livecharts :chart="new App\Charts\RevenueChart" />

The Livewire component handles mount, hydration, theme detection, and re-render. No JavaScript glue required.

6. Reactivity

Polling

$chart->poll(5000); // milliseconds

The component subscribes to wire:poll="refresh" and dispatches a browser event every tick:

window.addEventListener('livecharts:refreshed', (e) => {
    // e.detail.id — the chart's DOM id
})

To hydrate fresh data, override refresh() on a parent Livewire component (re-fetch your data, then re-emit the chart payload).

Click and zoom events

$chart
    ->onDataPointClick('chart-clicked')
    ->onZoom('chart-zoomed')
    ->onSelection('chart-selected')
    ->onScroll('chart-scrolled');
use Livewire\Attributes\On;

#[On('chart-clicked')]
public function handle(array $data): void
{
    // $data: ['seriesIndex' => 0, 'dataPointIndex' => 2, 'value' => 150, 'label' => 'Mar']
}

Broadcasting

$chart
    ->broadcastOn('private-charts.'.$user->id)
    ->broadcastAs('chart.updated');

Subscribe via Laravel Echo and the chart re-renders when the channel fires.

7. Engine selection

The default engine is set in config/livecharts.php:

'engine' => env('LIVECHARTS_ENGINE', 'apexcharts'),

Override per chart:

LiveCharts::line()->engine('chartjs')->labels(...)->dataset(...);

Register a custom engine adapter at runtime (typically in a service provider's boot()):

use App\LiveCharts\Engines\HighchartsAdapter;
use Matheusmarnt\LiveCharts\Facades\LiveCharts;

LiveCharts::registerEngine('highcharts', HighchartsAdapter::class);

The custom class must implement Matheusmarnt\LiveCharts\Contracts\EngineAdapter. Built-in adapters: apexcharts, chartjs.

Internal API change (v2.0+): EngineFactory::register() and EngineFactory::resolve() are now instance methods bound as a singleton on the container. Public callers should use the facade method above; advanced callers can resolve via app(EngineFactory::class).

Local assets

The package ships pre-built engine bundles via Vite (vite build) under resources/dist:

Bundle Source Purpose
livecharts.js resources/js/livecharts.js Alpine component + Livewire hooks
apexcharts.js npm apexcharts@^5.10.6 ApexCharts engine
chartjs.js npm chart.js@^4.5.1 Chart.js engine (UMD-mirrored named exports)
chartjs-treemap.js npm chartjs-chart-treemap Treemap plugin
chartjs-matrix.js npm chartjs-chart-matrix Matrix plugin
chartjs-sankey.js npm chartjs-chart-sankey Sankey plugin
chartjs-financial.js npm chartjs-chart-financial Candlestick plugin
chartjs-luxon.js + chartjs-adapter-luxon.js npm luxon + chartjs-adapter-luxon Time-axis adapter for candlestick

livecharts:install republishes all of these to public/vendor/livecharts/js. To re-publish on demand:

php artisan vendor:publish --tag=livecharts-assets --force

Switch modes:

LIVECHARTS_ASSETS_MODE=both   # default — local-first, CDN fallback via <script onerror>
LIVECHARTS_ASSETS_MODE=local  # no CDN
LIVECHARTS_ASSETS_MODE=cdn    # no local copy required

Under the navigate strategy (default), engine scripts are emitted via Livewire [@assets](https://github.com/assets) blocks — Livewire deduplicates them and re-ensures them across wire:navigate transitions. Under the stack strategy, [@liveChartsScripts](https://github.com/liveChartsScripts) emits the right <script> tags for the active mode and registers only the bundles required by the engines actually rendered on the page.

Building from source: if you fork the package or modify resources/js/livecharts.js, run npm ci && npm run build to regenerate the bundles. The js-build.yml workflow fails CI when the committed resources/dist/ is out of sync with the source.

Customization

Theme

use Matheusmarnt\LiveCharts\Enums\ThemeMode;

$chart->theme(ThemeMode::Auto);   // enum form (recommended)
$chart->theme('auto');            // string form — still supported

Available modes: ThemeMode::Auto, ThemeMode::Light, ThemeMode::Dark.

auto follows Tailwind's .dark class on <html> (default) or the prefers-color-scheme media query:

// config/livecharts.php
'theme' => [
    'mode'        => env('LIVECHARTS_THEME', 'auto'),
    'auto_detect' => env('LIVECHARTS_THEME_DETECT', 'class'), // 'class' | 'media'
],

Charts re-color live when the theme toggles — the JS observer patches updateOptions / chart.update directly, no Livewire roundtrip required.

Color tokens

v2.6+ ships TwColor, a 289-case backed enum covering all Tailwind v4 color families. Every chart element accepts dark: / light: named-arg pairs:

use Matheusmarnt\LiveCharts\Enums\TwColor;

$chart
    ->titleColor(dark: TwColor::Amber300, light: TwColor::Amber600)
    ->legendColor(dark: TwColor::Slate200, light: TwColor::Slate700)
    ->gridColor(dark: TwColor::Slate800, light: TwColor::Slate200)
    ->tooltipColor(dark: TwColor::White, light: TwColor::Slate900)
    ->backgroundColor(dark: TwColor::Slate900, light: TwColor::White);

Single-value form sets both themes to the same hex:

$chart->titleColor(TwColor::Slate500);
$chart->titleColor('#6b7280'); // plain hex still works

Dataset-level background/border split:

use Matheusmarnt\LiveCharts\Charts\Dataset;

Dataset::make('Revenue')
    ->data([100, 200, 150])
    ->backgroundColor(dark: TwColor::Emerald400, light: TwColor::Emerald600)
    ->borderColor(dark: TwColor::Emerald300, light: TwColor::Emerald700);

Palette presets auto-fill dataset colors:

use Matheusmarnt\LiveCharts\Enums\TwPalette;

$chart->palette(TwPalette::Vibrant); // Vibrant | Muted | Monochrome | Pastel | Neon

Helper methods on TwColor:

TwColor::Sky500->withAlpha(0.6);  // 'rgba(14,165,233,0.6)'
TwColor::Sky500->lighter(2);      // TwColor::Sky300
TwColor::Sky500->darker(1);       // TwColor::Sky600
TwColor::ramp('sky');             // [Sky50, Sky100, ..., Sky950]

Layout primitives

All ApexCharts/Chart.js layout primitives are exposed as fluent methods that merge into the engine's options:

$chart
    ->xaxis(['type' => 'datetime', 'tickAmount' => 6])
    ->yaxis(['min' => 0, 'forceNiceScale' => true])
    ->grid(['show' => false])
    ->stroke(['width' => 2, 'curve' => 'smooth'])
    ->markers(['size' => 4])
    ->dataLabels(['enabled' => false]);

Raw engine options

Escape hatch for engine-specific options not covered by fluent methods:

$chart->options([
    'chart' => ['animations' => ['enabled' => false]],
    'tooltip' => ['shared' => true, 'intersect' => false],
]);

Publish views

php artisan vendor:publish --tag=livecharts-views

Edits to the published Blade files override the package defaults.

Publish translations

php artisan vendor:publish --tag=livecharts-translations

Bundled locales: en, pt_BR, es.

Publish stubs (after install)

php artisan vendor:publish --tag=livecharts-stubs

Outputs stubs/livecharts/chart.php.stub. make:chart reads the application stub if present, falling back to the package default.

Updating

composer update matheusmarnt/livecharts
php artisan vendor:publish --tag=livecharts-config --force
php artisan vendor:publish --tag=livecharts-assets --force  # only if running in local asset mode

When upgrading across a major version (e.g. 1.x → 2.x) review CHANGELOG.md for breaking changes before running --force on the config.

Preview Route

The package ships a debug route that renders one of every chart type for visual smoke-testing. Open it in your default browser with:

php artisan livecharts:preview            # opens the URL via the OS-native opener
php artisan livecharts:preview --no-open  # only prints the URL (CI / headless)

The command detects the host OS and spawns the appropriate opener (open on macOS, xdg-open on Linux/BSD, cmd /c start on Windows). On failure it falls back to printing the URL with the warning string from livecharts.preview.open_failed.

The route is registered automatically at /livecharts/preview under the web middleware group — make sure your local server (php artisan serve, Sail, or Docker) is running before invoking the command. Restrict or disable the route in production by overriding LiveChartsServiceProvider::registerRoutes() from a child provider, or by gating it via middleware in your application.

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.
babenkoivan/elastic-client
innmind/static-analysis
innmind/coding-standard
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony