Laravel package for generating clean and reusable dashboard
Most dashboards start innocently: a card for total users, another one for total orders, then revenue, average order value, chart data, percentage change, and eventually caching because the dashboard is now doing too much work on every request.
At first, this feels fine because each statistic is “just a query”. But as the application grows, the same logic starts appearing in controllers, services, widgets, reports, and API endpoints.
That is the kind of small but annoying problem I wanted to solve with Laravel Statistician.
Laravel Statistician is a Laravel package for generating clean application statistics from Eloquent models, query builders, model classes, or plain table names.
The goal is simple: keep dashboard and reporting logic reusable instead of duplicating query logic everywhere.
Repository:
https://github.com/omaressaouaf/laravel-statistician
The Problem
In many Laravel applications, dashboard statistics begin like this:
$totalUsers = User::count();
$totalOrders = Order::count();
$totalRevenue = Order::sum('total');
$averageOrderValue = Order::avg('total');
This is perfectly fine in the beginning. The problem appears later, when the dashboard needs date filters, chart data, percentage changes, cached numbers, and similar metrics reused in different places.
At that point, the issue is no longer that the queries are difficult. The issue is that they are easy enough to duplicate.
A controller has one version of the logic. An admin widget has another. A report export has another. An API endpoint has another.
Over time, these small duplicated queries create inconsistency across the codebase.
What Laravel Statistician Does
Laravel Statistician provides a cleaner way to define and generate application statistics.
It supports common dashboard needs such as aggregate statistics, date-range filtering, date-grouped statistics for charts, percentage changes between periods, trend statistics, multiple statistics in one call, caching, and custom keys.
It is not trying to be a full analytics platform or a BI tool. It is a small package for the kind of statistics most Laravel applications need in dashboards, admin panels, reports, and internal tools.
Installation
You can install it with Composer:
composer require omaressaouaf/laravel-statistician
Basic Aggregate Statistic
Here is a simple example that counts users:
use App\Models\User;
use Omaressaouaf\LaravelStatistician\Enums\Aggregate;
use Omaressaouaf\LaravelStatistician\Sources\AggregateSource;
use Omaressaouaf\LaravelStatistician\Statisticians\AggregateStatistician;
$stats = AggregateStatistician::fromSources(
new AggregateSource(User::class, Aggregate::COUNT)
)->get();
echo $stats['users_count'];
Instead of writing the query directly inside a controller or dashboard widget, the statistic becomes a structured source. That makes it easier to reuse, extend, and compose with other statistics.
Custom Keys
By default, the package generates a key based on the source and aggregate. You can also define your own key:
$stats = AggregateStatistician::fromSources(
(new AggregateSource(User::class, Aggregate::COUNT))->keyBy('total_users')
)->get();
echo $stats['total_users'];
This is useful when you want your dashboard response to have clean and predictable names.
Date Range Filtering
Most dashboard statistics are not global. You usually want numbers for today, this week, this month, this year, or a custom date range.
Laravel Statistician allows you to apply a start and end date:
$stats = AggregateStatistician::fromSources(
new AggregateSource(User::class, Aggregate::COUNT)
)
->start('2025-01-01')
->end('2025-12-31')
->get();
This keeps date filtering consistent across different statistics.
Multiple Statistics in One Call
A common dashboard pattern is returning several numbers together, such as users, orders, and revenue.
use App\Models\User;
use App\Models\Order;
use Omaressaouaf\LaravelStatistician\Enums\Aggregate;
use Omaressaouaf\LaravelStatistician\Sources\AggregateSource;
use Omaressaouaf\LaravelStatistician\Statisticians\AggregateStatistician;
$stats = AggregateStatistician::fromSources(
(new AggregateSource(User::class, Aggregate::COUNT))->keyBy('users'),
(new AggregateSource(Order::class, Aggregate::COUNT))->keyBy('orders'),
(new AggregateSource(Order::class, Aggregate::SUM, 'total'))->keyBy('revenue'),
)->get();
return $stats;
This keeps related dashboard metrics grouped together instead of scattering them across multiple methods or services.
Sum, Average, Min, and Max
You are not limited to counts. For example, you can calculate order statistics like this:
use App\Models\Order;
use Omaressaouaf\LaravelStatistician\Enums\Aggregate;
use Omaressaouaf\LaravelStatistician\Sources\AggregateSource;
use Omaressaouaf\LaravelStatistician\Statisticians\AggregateStatistician;
$stats = AggregateStatistician::fromSources(
new AggregateSource(Order::class, Aggregate::SUM, 'total'),
new AggregateSource(Order::class, Aggregate::AVG, 'total'),
new AggregateSource(Order::class, Aggregate::MAX, 'total'),
)->get();
This can be useful for ecommerce dashboards, SaaS admin panels, financial reports, and internal business tools.
Date-Grouped Statistics for Charts
Dashboard charts usually need data grouped by date: users registered per day, orders per day, revenue per month, tickets created per week, and so on.
Laravel Statistician includes date-grouped statistics:
use App\Models\User;
use Omaressaouaf\LaravelStatistician\Enums\Aggregate;
use Omaressaouaf\LaravelStatistician\Sources\DateGroupedAggregateSource;
use Omaressaouaf\LaravelStatistician\Statisticians\DateGroupedAggregateStatistician;
$stats = DateGroupedAggregateStatistician::fromSources(
new DateGroupedAggregateSource(User::class, Aggregate::COUNT)
)
->start('2025-01-01')
->end('2025-01-31')
->get();
Example result:
[
'users_count_by_date' => [
'data' => [
['date_label' => '2025-01-01', 'aggregate' => 10],
['date_label' => '2025-01-02', 'aggregate' => 15],
],
'date_format' => 'Y-m-d',
],
]
This is useful when building chart components because the data can be generated in a consistent format instead of being prepared manually every time.
Percentage Change
Dashboards are usually more useful when they show context. “1,200 users” is useful, but “1,200 users, up 18% compared to the previous period” is much better.
Laravel Statistician supports percentage change between periods:
use App\Models\User;
use Omaressaouaf\LaravelStatistician\Sources\PercentageChangeSource;
use Omaressaouaf\LaravelStatistician\Statisticians\PercentageChangeStatistician;
$stats = PercentageChangeStatistician::fromSources(
new PercentageChangeSource(User::class)
)
->start('2025-02-01')
->end('2025-02-28')
->get();
echo $stats['users_percentage_change'];
This helps when building dashboard cards that compare current performance with a previous period.
Using Query Builders
Sometimes a statistic is not based on an entire model. You may want to count only active users, completed orders, paid invoices, or filtered records.
The package also works with query builders:
use Illuminate\Support\Facades\DB;
use Omaressaouaf\LaravelStatistician\Enums\Aggregate;
use Omaressaouaf\LaravelStatistician\Sources\AggregateSource;
use Omaressaouaf\LaravelStatistician\Statisticians\AggregateStatistician;
$stats = AggregateStatistician::fromSources(
new AggregateSource(DB::table('users')->where('is_active', true), Aggregate::COUNT)
)->get();
This makes it flexible enough for real-world use cases where statistics often depend on business rules.
Caching Statistics
Some dashboard statistics do not need to be recalculated on every request. Laravel Statistician supports caching:
$stats = AggregateStatistician::fromSources(
new AggregateSource(User::class)
)
->cacheFor(3600)
->get();
You can also cache until a specific date:
$stats = AggregateStatistician::fromSources(
new AggregateSource(User::class)
)
->cacheUntil(now()->addDay())
->get();
And clear the cache conditionally:
$stats = AggregateStatistician::fromSources(
new AggregateSource(User::class)
)
->clearCacheWhen(request()->boolean('refresh'))
->cacheFor(3600)
->get();
This is useful for dashboards where users expect fast responses, but the data does not need to be refreshed every second.
Why I Built It
I like small packages that solve boring problems cleanly.
Dashboard statistics are not usually the hardest part of a Laravel application, but they can easily make the codebase messy. The pattern often looks like this:
// Controller
$totalUsers = User::whereBetween('created_at', [$start, $end])->count();
// Somewhere else
$users = User::whereDate('created_at', '>=', $start)
->whereDate('created_at', '<=', $end)
->count();
// Another dashboard widget
$userCount = User::query()
->whereBetween('created_at', [$from, $to])
->count();
None of this is terrible alone. But over time, it creates inconsistency.
Laravel Statistician is a small abstraction around this pattern. Not a heavy analytics system. Not a complex reporting engine. Just a cleaner way to define, reuse, cache, and return statistics.
Design Philosophy
The package follows a few simple principles.
First, the API should stay easy to read. A developer should be able to understand what is being calculated without jumping through multiple files.
Second, it should support common dashboard needs first: aggregates, date ranges, chart data, comparison stats, and caching.
Third, it should work with existing Laravel patterns. The package supports Eloquent models, query builders, model classes, and table names instead of forcing a new data layer.
Finally, it should stay extensible. Every application eventually has custom business metrics, so the package allows custom statisticians while preserving the same general developer experience.
When This Package Is Useful
Laravel Statistician can be useful for admin dashboards, SaaS dashboards, ecommerce reports, internal tools, CRM statistics, financial summaries, user activity reports, chart APIs, and KPI widgets.
It is especially useful when multiple parts of the application need similar statistics.
When You May Not Need It
You probably do not need this package if your dashboard has only one or two simple numbers, your statistics are extremely custom, you already use a dedicated analytics system, or your data is processed in a separate warehouse or BI tool.
This package is meant for application-level statistics inside Laravel apps. It is not meant to replace full analytics infrastructure.
Final Thoughts
Statistics logic is one of those things that feels too small to abstract at first. But once the dashboard grows, the duplication becomes obvious.
Laravel Statistician is my attempt to make this part of Laravel applications cleaner: define statistics once, reuse them, group them, cache them, and return them in a predictable format.
The package is open source, and I would love feedback from Laravel developers.
Repository:
https://github.com/omaressaouaf/laravel-statistician
If you build dashboards in Laravel, I hope this package saves you from writing the same statistics queries again and again.