npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kodeme-io/next-core-analytics

v0.8.4

Published

Analytics, charts, dashboards, and reporting for Next.js applications

Readme

@kodeme-io/next-core-analytics

Analytics, charts, dashboards, and reporting components for Next.js applications with TypeScript support and real-time data visualization.

🚀 Features

  • 📊 KPI Cards - Display key metrics with trends and comparisons
  • 📈 Rich Charts - Line, bar, pie, donut, area, scatter, radar charts using Recharts
  • 🎯 Dashboard Builder - Create custom, responsive dashboards
  • 📁 Export Functionality - PDF, Excel, CSV, JSON export with real library implementations
  • 📊 Data Aggregation - Sum, avg, min, max, count with grouping
  • ⏰ Time Series Analysis - Time-based data processing and visualization
  • 🔄 Real-time Updates - Live data streaming and WebSocket support
  • ♿ Accessible - WCAG compliant with keyboard navigation
  • 🔧 TypeScript Native - Full type safety and IntelliSense support
  • 🌍 Internationalization - Built-in support for multiple locales and currencies
  • ✅ Data Validation - Zod-powered validation for all data inputs
  • 🛡️ Error Boundaries - Graceful error handling and recovery
  • ⚡ Performance Optimized - React.memo and useMemo optimizations

📦 Installation

npm install @kodeme-io/next-core-analytics
# or
yarn add @kodeme-io/next-core-analytics
# or
pnpm add @kodeme-io/next-core-analytics

Peer Dependencies

npm install react react-dom recharts date-fns

Dependencies

The package includes the following dependencies:

  • recharts - Chart rendering
  • date-fns - Date manipulation
  • jspdf - PDF export
  • xlsx - Excel export
  • zod - Data validation

🎯 Quick Start

Basic Analytics Dashboard

'use client'

import {
  KPICard,
  ChartContainer,
  Dashboard,
  useAnalytics,
  type KPIMetric,
  type ChartConfig,
  type DashboardLayout
} from '@kodeme-io/next-core-analytics'

const salesMetrics: KPIMetric[] = [
  {
    id: 'revenue',
    label: 'Total Revenue',
    value: 2500000,
    previousValue: 2100000,
    format: 'currency',
    trend: 'up',
    trendValue: 19.0,
    icon: <div>💰</div>,
    color: 'text-green-600'
  },
  {
    id: 'orders',
    label: 'Total Orders',
    value: 1250,
    previousValue: 1100,
    format: 'number',
    trend: 'up',
    trendValue: 13.6,
    icon: <div>📦</div>,
    color: 'text-blue-600'
  },
  {
    id: 'conversion',
    label: 'Conversion Rate',
    value: 3.2,
    previousValue: 2.8,
    format: 'percentage',
    trend: 'up',
    trendValue: 14.3,
    icon: <div>📈</div>,
    color: 'text-purple-600'
  }
]

const salesChartConfig: ChartConfig = {
  type: 'line',
  data: [
    { name: 'Jan', value: 1800000 },
    { name: 'Feb', value: 2100000 },
    { name: 'Mar', value: 2500000 },
    { name: 'Apr', value: 2300000 },
    { name: 'May', value: 2800000 },
    { name: 'Jun', value: 2500000 }
  ],
  xKey: 'name',
  yKey: 'value',
  colors: ['#3b82f6'],
  title: 'Monthly Revenue Trend',
  subtitle: 'Revenue performance over the last 6 months'
}

const salesDashboard: DashboardLayout = {
  id: 'sales-dashboard',
  name: 'Sales Dashboard',
  widgets: [
    {
      id: 'kpi-row',
      type: 'kpi',
      title: 'Key Metrics',
      config: { metrics: salesMetrics },
      span: { cols: 12, rows: 2 }
    },
    {
      id: 'revenue-chart',
      type: 'chart',
      title: 'Revenue Trend',
      config: salesChartConfig,
      span: { cols: 8, rows: 4 }
    }
  ],
  refreshInterval: 300
}

export default function SalesDashboard() {
  const { data, loading, error, refresh } = useAnalytics({
    endpoint: '/api/analytics/sales',
    params: { period: '6m' },
    refreshInterval: 30000 // 30 seconds
  })

  if (loading) return <div>Loading dashboard...</div>
  if (error) return <div>Error loading dashboard</div>

  return (
    <div className="p-6">
      <div className="flex justify-between items-center mb-6">
        <h1 className="text-3xl font-bold">Sales Analytics</h1>
        <button
          onClick={refresh}
          className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
        >
          Refresh
        </button>
      </div>

      <Dashboard layout={salesDashboard} data={data} />
    </div>
  )
}

📚 Core Concepts

KPI Card Structure

interface KPIMetric {
  id: string                    // Unique metric identifier
  label: string                 // Display label
  value: number | string       // Current value
  previousValue?: number       // Previous period value
  format?: 'number' | 'currency' | 'percentage' | 'duration'  // Value formatting
  trend?: 'up' | 'down' | 'neutral'  // Trend direction
  trendValue?: number          // Trend percentage
  icon?: React.ReactNode       // Custom icon
  color?: string              // Custom color class
  prefix?: string             // Value prefix
  suffix?: string             // Value suffix
  // Internationalization options
  locale?: string             // Locale for number formatting (e.g., 'en-US', 'de-DE')
  currency?: string           // Currency code (e.g., 'USD', 'EUR', 'IDR')
  numberFormatOptions?: Intl.NumberFormatOptions  // Custom formatting options
}

Chart Configuration

interface ChartConfig {
  type: ChartType              // Chart type (line, bar, area, pie, donut, scatter, radar)
  data: ChartDataPoint[]      // Chart data
  xKey?: string              // X-axis data key
  yKey?: string | string[]   // Y-axis data key(s)
  colors?: string[]          // Custom colors
  legend?: boolean           // Show legend
  grid?: boolean            // Show grid
  tooltip?: boolean          // Show tooltip
  title?: string            // Chart title
  subtitle?: string         // Chart subtitle
}

Dashboard Layout

interface DashboardLayout {
  id: string                    // Dashboard identifier
  name: string                 // Dashboard name
  widgets: DashboardWidget[]   // Dashboard widgets
  refreshInterval?: number     // Auto-refresh interval (seconds)
  filters?: DashboardFilter[]  // Dashboard filters
}

interface DashboardWidget {
  id: string                    // Widget identifier
  type: 'chart' | 'kpi' | 'table' | 'custom'  // Widget type
  title: string                 // Widget title
  description?: string          // Widget description
  config: ChartConfig | KPICardConfig | any  // Widget configuration
  span?: {                     // Grid span
    cols?: number              // Column span (1-12)
    rows?: number              // Row span (1-6)
  }
}

🎨 Components

KPICard

Display key performance metrics with optional trends and comparisons:

<KPICard
  metric={{
    id: 'revenue',
    label: 'Total Revenue',
    value: 1500000,
    previousValue: 1200000,
    format: 'currency',
    trend: 'up',
    trendValue: 25,
    icon: <RevenueIcon />,
    color: 'text-green-600'
  }}
  variant="default"  // 'default' | 'compact' | 'detailed'
  className="custom-kpi-card"
/>

Variants:

  • default - Standard card with trend and value
  • compact - Minimal design for dense layouts
  • detailed - Extended view with previous values

Formats:

  • number - Formatted with thousand separators
  • currency - IDR currency format (default)
  • percentage - Percentage with decimal precision
  • duration - Hours and minutes format

ChartContainer

Responsive chart wrapper with loading and error states:

<ChartContainer
  config={{
    type: 'line',
    data: salesData,
    xKey: 'month',
    yKey: 'revenue',
    colors: ['#3b82f6'],
    title: 'Monthly Revenue',
    grid: true,
    tooltip: true
  }}
  loading={false}
  error={null}
  className="chart-container"
  height={400}
/>

Chart Types:

  • line - Line charts for trends
  • bar - Bar charts for comparisons
  • area - Area charts for cumulative data
  • pie - Pie charts for proportions
  • donut - Donut charts with center space
  • scatter - Scatter plots for correlations
  • radar - Radar charts for multi-dimensional data

Dashboard

Full dashboard layout with grid system and widgets:

<Dashboard
  layout={dashboardLayout}
  data={analyticsData}
  onWidgetClick={(widgetId) => console.log('Widget clicked:', widgetId)}
  onFilterChange={(filters) => console.log('Filters changed:', filters)}
  className="analytics-dashboard"
  loading={false}
  error={null}
/>

ExportButton

Export dashboard or chart data in multiple formats:

<ExportButton
  config={{
    format: 'pdf',
    filename: 'sales-report',
    data: chartData,
    title: 'Sales Report',
    includeCharts: true
  }}
  onExportComplete={(filename) => console.log('Exported:', filename)}
  className="export-button"
/>

Export Formats:

  • pdf - PDF reports with charts and tables
  • excel - Excel spreadsheets with multiple sheets
  • csv - CSV files for data analysis
  • json - JSON data for integration

📊 Data Processing

Data Aggregation

import { aggregateData } from '@kodeme-io/next-core-analytics'

// Aggregate sales data by region
const aggregatedSales = aggregateData(salesData, {
  field: 'revenue',
  type: 'sum',
  groupBy: 'region'
})

// Calculate average order value
const avgOrderValue = aggregateData(orderData, {
  field: 'orderValue',
  type: 'avg'
})

Aggregation Types:

  • sum - Sum of values
  • avg - Average of values
  • min - Minimum value
  • max - Maximum value
  • count - Count of records

Time Series Processing

import { processTimeSeries } from '@kodeme-io/next-core-analytics'

// Process daily sales data into weekly aggregates
const weeklyData = processTimeSeries(dailySales, {
  dateField: 'date',
  valueField: 'revenue',
  granularity: 'week',
  fillGaps: true
})

Time Granularities:

  • hour - Hourly aggregation
  • day - Daily aggregation
  • week - Weekly aggregation
  • month - Monthly aggregation
  • quarter - Quarterly aggregation
  • year - Yearly aggregation

Comparison Analysis

import { calculateComparison } from '@kodeme-io/next-core-analytics'

// Calculate period-over-period growth
const comparison = calculateComparison({
  currentPeriod: { start: new Date('2024-01-01'), end: new Date('2024-01-31') },
  previousPeriod: { start: new Date('2023-12-01'), end: new Date('2023-12-31') },
  metric: 'revenue',
  data: salesData
})

console.log(`Revenue ${comparison.trend === 'up' ? 'increased' : 'decreased'} by ${comparison.percentChange}%`)

🔄 Advanced Usage

Real-time Data

function RealTimeDashboard() {
  const { data, subscribe, unsubscribe } = useAnalytics({
    endpoint: '/api/analytics/realtime',
    realtime: true
  })

  useEffect(() => {
    const handleRealtimeUpdate = (newData) => {
      console.log('Real-time data update:', newData)
    }

    subscribe('data-updated', handleRealtimeUpdate)

    return () => {
      unsubscribe('data-updated')
    }
  }, [subscribe, unsubscribe])

  return (
    <Dashboard layout={realtimeLayout} data={data} />
  )
}

Custom Charts

import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts'

function CustomSalesChart({ data }: { data: any[] }) {
  return (
    <ResponsiveContainer width="100%" height={400}>
      <LineChart data={data}>
        <CartesianGrid strokeDasharray="3 3" />
        <XAxis dataKey="month" />
        <YAxis />
        <Tooltip />
        <Line
          type="monotone"
          dataKey="revenue"
          stroke="#3b82f6"
          strokeWidth={2}
          dot={{ fill: '#3b82f6', strokeWidth: 2, r: 4 }}
          activeDot={{ r: 6 }}
        />
      </LineChart>
    </ResponsiveContainer>
  )
}

Multi-series Charts

const multiSeriesConfig: ChartConfig = {
  type: 'line',
  data: [
    { month: 'Jan', revenue: 1000000, profit: 200000, expenses: 800000 },
    { month: 'Feb', revenue: 1200000, profit: 250000, expenses: 950000 },
    { month: 'Mar', revenue: 1100000, profit: 180000, expenses: 920000 }
  ],
  xKey: 'month',
  yKey: ['revenue', 'profit', 'expenses'],
  colors: ['#3b82f6', '#10b981', '#ef4444'],
  title: 'Financial Overview',
  legend: true
}

Custom Dashboard Filters

const dashboardWithFilters: DashboardLayout = {
  id: 'filtered-dashboard',
  name: 'Filtered Dashboard',
  widgets: [/* ... */],
  filters: [
    {
      id: 'date-range',
      type: 'date',
      label: 'Date Range',
      value: { start: '2024-01-01', end: '2024-12-31' }
    },
    {
      id: 'region',
      type: 'multiselect',
      label: 'Regions',
      value: ['all'],
      options: [
        { label: 'All Regions', value: 'all' },
        { label: 'North America', value: 'na' },
        { label: 'Europe', value: 'eu' },
        { label: 'Asia Pacific', value: 'apac' }
      ]
    },
    {
      id: 'product-category',
      type: 'select',
      label: 'Product Category',
      value: 'all',
      options: [
        { label: 'All Categories', value: 'all' },
        { label: 'Electronics', value: 'electronics' },
        { label: 'Clothing', value: 'clothing' },
        { label: 'Food', value: 'food' }
      ]
    }
  ]
}

🎨 Styling and Theming

Custom Color Schemes

const customTheme = {
  primary: '#6366f1',
  secondary: '#8b5cf6',
  success: '#10b981',
  warning: '#f59e0b',
  error: '#ef4444',
  neutral: '#6b7280'
}

const themedChartConfig: ChartConfig = {
  type: 'bar',
  data: salesData,
  xKey: 'month',
  yKey: 'revenue',
  colors: [customTheme.primary, customTheme.secondary],
  title: 'Sales by Month'
}

Responsive Design

// Responsive grid layout
const responsiveDashboard: DashboardLayout = {
  id: 'responsive-dashboard',
  name: 'Responsive Dashboard',
  widgets: [
    {
      id: 'kpi-cards',
      type: 'kpi',
      title: 'Metrics',
      config: { metrics: kpiMetrics },
      span: { cols: 12, rows: 2 }  // Full width on desktop
    },
    {
      id: 'main-chart',
      type: 'chart',
      title: 'Trends',
      config: chartConfig,
      span: { cols: 8, rows: 4 }   // 8/12 columns
    },
    {
      id: 'secondary-chart',
      type: 'chart',
      title: 'Breakdown',
      config: pieChartConfig,
      span: { cols: 4, rows: 4 }   // 4/12 columns
    }
  ]
}

🧪 Testing

The package includes comprehensive test coverage:

# Run tests
npm test

# Run with coverage
npm run test:coverage

# Run tests in watch mode
npm run test:watch

Testing Analytics Components

import { render, screen } from '@testing-library/react'
import { KPICard } from '@kodeme-io/next-core-analytics'

test('KPI card renders correctly', () => {
  const metric = {
    id: 'test-metric',
    label: 'Test Metric',
    value: 1000,
    format: 'number' as const,
    trend: 'up' as const,
    trendValue: 10
  }

  render(<KPICard metric={metric} />)

  expect(screen.getByText('Test Metric')).toBeInTheDocument()
  expect(screen.getByText('1.000')).toBeInTheDocument()
  expect(screen.getByText('10%')).toBeInTheDocument()
})

🌍 Internationalization

Currency and Number Formatting

The analytics package now supports internationalization out of the box:

import { KPICard, currencyFormatters } from '@kodeme-io/next-core-analytics'

// Indonesian Rupiah
<KPICard
  metric={{
    id: 'revenue',
    label: 'Total Revenue',
    value: 1500000,
    format: 'currency',
    locale: 'id-ID',
    currency: 'IDR'
  }}
/>

// Euro with German locale
<KPICard
  metric={{
    id: 'revenue-eur',
    label: 'Revenue (EUR)',
    value: 1500,
    format: 'currency',
    locale: 'de-DE',
    currency: 'EUR'
  }}
/>

// Or use pre-configured formatters
const formattedValue = currencyFormatters.EUR(1500)

Custom Formatters

import { createFormatter, formatValue } from '@kodeme-io/next-core-analytics'

const customFormatter = createFormatter({
  format: 'currency',
  currency: 'GBP',
  locale: 'en-GB'
})

✅ Data Validation

Built-in Validation

All components include automatic data validation using Zod schemas:

import { KPICard, validateKPI, KPIMetricSchema } from '@kodeme-io/next-core-analytics'

// Manual validation
const isValidKPI = validateKPI(kpiData)

// Safe validation with error handling
import { safeValidate } from '@kodeme-io/next-core-analytics'
const result = safeValidate(KPIMetricSchema, metricData)
if (!result.success) {
  console.error('Validation errors:', result.errors)
}

Performance Monitoring

import { validationMonitor } from '@kodeme-io/next-core-analytics'

// Get validation statistics
const stats = validationMonitor.getStats()
console.log('Average validation time:', stats.averageValidationTime)
console.log('Success rate:', stats.successRate)

🛡️ Error Boundaries

Component-Level Error Handling

import {
  AnalyticsErrorBoundary,
  KPIErrorBoundary,
  ChartErrorBoundary,
  DashboardErrorBoundary
} from '@kodeme-io/next-core-analytics'

// Wrap your entire dashboard
<DashboardErrorBoundary>
  <Dashboard layout={dashboardLayout} />
</DashboardErrorBoundary>

// Or specific components
<KPIErrorBoundary>
  <KPICard metric={metric} />
</KPIErrorBoundary>

<ChartErrorBoundary>
  <ChartContainer config={chartConfig} />
</ChartErrorBoundary>

Error Handling Hooks

import { useErrorHandler } from '@kodeme-io/next-core-analytics'

function MyComponent() {
  const { error, captureError, resetError } = useErrorHandler()

  if (error) {
    return (
      <div>
        <p>Error: {error.message}</p>
        <button onClick={resetError}>Retry</button>
      </div>
    )
  }

  // Your component logic
}

🔧 API Reference

Hooks

// Main analytics hook (enhanced with real API support)
export function useAnalytics(options?: {
  endpoint?: string
  params?: Record<string, any>
  refreshInterval?: number
  realtime?: boolean
  method?: 'GET' | 'POST'
  headers?: Record<string, string>
  cache?: RequestCache
}): {
  data: any
  loading: boolean
  error: Error | null
  refresh: () => void
  subscribe: (event: string, callback: Function) => void
  unsubscribe: (event: string) => void
}

// Error handling hook
export function useErrorHandler(): {
  error: Error | null
  captureError: (error: Error) => void
  resetError: () => void
}

Utilities

// Data aggregation
export function aggregateData(data: any[], config: AggregationConfig): any[]

// Time series processing
export function processTimeSeries(data: any[], config: TimeSeriesConfig): any[]

// Comparison analysis
export function calculateComparison(config: ComparisonConfig): ComparisonData

// Formatting utilities
export function formatValue(value: number | string, options: FormatValueOptions): string
export function formatTrendValue(value: number, format?: 'percentage' | 'number'): string
export function formatDuration(seconds: number): string

// Validation utilities
export function validateKPI(metric: unknown): KPIMetric
export function validateChartData(data: unknown[]): ChartDataPoint[]
export function validateDashboardLayout(layout: unknown): DashboardLayout
export function safeValidate<T>(schema: z.ZodSchema<T>, data: unknown): ValidationResult<T>

Component Props

// KPICard props
export interface KPICardProps {
  metric: KPIMetric
  variant?: 'default' | 'compact' | 'detailed'
  className?: string
}

// ChartContainer props
export interface ChartContainerProps {
  config: ChartConfig
  loading?: boolean
  error?: string | null
  className?: string
  height?: number
}

// Dashboard props
export interface DashboardProps {
  layout: DashboardLayout
  data?: any
  onWidgetClick?: (widgetId: string) => void
  onFilterChange?: (filters: Record<string, any>) => void
  className?: string
  loading?: boolean
  error?: string | null
}

🔍 Troubleshooting

Common Issues

  1. Charts Not Rendering

    • Check if data is properly formatted
    • Verify xKey and yKey match data structure
    • Ensure recharts is installed as a dependency
  2. KPI Values Not Formatting

    • Verify format type matches value type
    • Check if value is number for numeric formats
    • Ensure locale settings are correct
  3. Export Not Working

    • Check if export libraries are installed
    • Verify data structure matches export requirements
    • Ensure proper file permissions

Debug Mode

Enable debug logging:

const analytics = useAnalytics({
  endpoint: '/api/analytics',
  debug: true
})

🚀 Performance Tips

  1. Data Caching - Cache API responses to reduce network requests
  2. Virtualization - Use virtual scrolling for large datasets
  3. Lazy Loading - Load charts and data on demand
  4. Debounced Updates - Debounce real-time data updates
  5. Component Memoization - Components are optimized with React.memo
  6. Value Memoization - Expensive calculations are memoized
// Caching example
const cachedAnalytics = useMemo(() => {
  return processAnalyticsData(rawData)
}, [rawData])

// Debounced refresh
const debouncedRefresh = useMemo(
  () => debounce(refresh, 1000),
  [refresh]
)

// Components are already optimized - no manual memoization needed
<KPICard metric={metric} variant="compact" />
<ChartContainer config={chartConfig} />

Performance Monitoring

The package includes built-in performance monitoring:

import { validationMonitor } from '@kodeme-io/next-core-analytics'

// Get real-time performance metrics
const stats = validationMonitor.getStats()
console.log({
  totalValidations: stats.totalValidations,
  averageTime: stats.averageValidationTime,
  successRate: stats.successRate
})

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Submit a pull request

📄 License

MIT License - see LICENSE file for details

🔗 Related Packages

📞 Support