Changelog (1.1.0)

June 29, 2026 · 5 min read

v1.1.0 - Provider refactor, Chart Types, Widgets & Private Views

Chart Types

TypeWhat you get
2D ChartTypical 2D charts, uses Rechart
AggregateKPI summary cards showing the aggregated value for each stat
ListPaginated data tables with aggregate rows (sum, average, min, max, count)
CustomCustom chart types - suspended until bug with LayoutComposer is resolved

Widget for Dashboard Embedding

You can now embed charts as a standalone widget anywhere in the Medusa admin dashboard. The widget handles its own data fetching and renders independently.

Revamped UIs

All user interfaces were revamped to improve the visual attractiveness and UX.

Internationalization

All UI text is now translatable. English translations are built-in under the stats namespace.

Providers now also provide their own translation files for their metrics and parameters.

Private Views

You can mark a view as private so only you see it.


Providers

Provider API Rewrite

The providers were rewritten to use a decorator-based API to allow for better DX and less redundancy.

class MyProvider extends AbstractStatisticsProvider {
  static identifier = "my-provider"

  @StatFn("total_orders", {
    schema: z.object({ status: z.enum(["completed", "pending"]).default("completed") }),
    dimension: "time",
  })
  async totalOrders({ parameters, ...input }: StatCalculationInput): Promise<StatisticResult> {
    const timeSeries = await createQueryTimeSeries(this.query, input, {
      entity: "order",
      fields: ["id", "created_at"],
      filters: { status: parameters.status },
    }, count())

    return { value: timeSeries }
  }
}
  • StatBuilder - removed, use @StatFn instead.
  • getAvailableStatistics() and calculateStatistic() - removed.
  • displayName - removed, use i18n translation files instead.

New Shared Utilities

These are exported from medusa-stats and available in your custom providers:

ExportWhat it does
createTimeSeries(data, start, end, interval, accumulator)Bucket pre-fetched data into time intervals
createQueryTimeSeries(query, input, config, accumulator)Query an entity and bucket results in one call
count()Accumulator: number of items per bucket
sum("field")Accumulator: sum of a numeric field per bucket
average("field")Accumulator: average of a numeric field per bucket
groupBy(data, keySelector, aggregator?)Group data by a key with optional aggregation
generateIntervals(start, end, interval)Generate interval timestamps for a period
getIntervalBucket(date, periodStart, interval)Get the interval bucket for a given date
extractFieldsFromZodSchema(schema)Derive parameter metadata from a Zod schema

You can also pass a custom accumulator function to createTimeSeries or createQueryTimeSeries for arbitrary per-bucket logic.

New API Routes

RouteMethodPurpose
/admin/statistics/calculatePOSTAd-hoc calculation without a view — used by the widget
/admin/statistics/chart-typesGETReturns available chart types (2d, aggregate, list)