EasyKPI

EasyKPI — Analyst Workbench

Live site (read-only catalog preview) → x7-u.github.io/EasyKPI

EasyKPI is a fully local, browser-based KPI analytics workbench. Clone the repo, run EasyKPI.exe on Windows (or npm install && npm run dev on any OS), and you get charts, forecasting, benchmarks, data ingest, goal-seek, anomaly detection, AI narratives, dashboards, and Excel export — all running on your own machine, with nothing leaving it unless you explicitly configure a cloud connector.

The hosted link above is the original static catalog kept for quick browsing. Everything described below is what you get when you run the full workbench locally.


Feature showcase

A curated catalog of 95 KPIs

Every KPI in the catalog ships with:

Browse by any combination of:

Real charts on every KPI

No more “recommended chart type: Line Chart” with nothing drawn. Every KPI detail page renders a live chart (ECharts) on your data — or a deterministic mock series before you’ve uploaded anything. The single <KPIChart> adapter handles every chart variant (line, bar, area) plus every overlay:

Targets and traffic-light status

Set a target for any KPI and the app colours every instance of it green / amber / red based on:

Traffic-light badges show on every KPI card, catalog result, dashboard tile, comparison column, and KPI detail header.

Seeded industry benchmarks

Out of the box you get seeded p25 / p50 / p75 benchmarks for 15 of the most commonly used KPIs:

Revenue Growth, Net Profit Margin, Gross Profit Margin, Current Ratio, DSO, Conversion Rate, Win Rate, CAC, ROAS, CTR, NPS, CLV, Retention Rate, Churn Rate, OEE.

Chart bands and benchmark panels pick these up automatically. Custom workspace-scoped benchmarks live in the database and override the seeded values when present.

A calculator with three modes

Every one of the 95 KPIs has a first-class calculator with three tabs:

  1. Single — type the inputs, see the answer. Unit-aware output (%, $, or a unit-less number) formatted to the KPI’s precision.
  2. Series — paste a CSV (first column period, remaining columns match the formula inputs). The formula runs row-wise and the result is charted inline. One click exports the computed series to Excel.
  3. Goal-seek — pick which input to solve for, set the target output, and the app inverts the formula numerically (bisection with a Newton fallback). Works for every formula, no extra code per KPI.

Data ingest — CSV, XLSX, and SQL

Turn EasyKPI from a reference tool into a tool that answers your questions:

Forecasting, anomalies, and decomposition

The shared analytics package gives every chart a Phase-3 toolkit:

AI assistance via Claude

Drag-and-drop dashboards

Excel export, two ways

  1. Per-chart export — a button on every chart (catalog detail, calculator, dashboard tile). One sheet, metadata header, period / value / target / benchmark_* / forecast_* / anomaly columns, number-formatted per KPI precision. Client-side (SheetJS), no server required.
  2. Multi-sheet dashboard export — server-side via ExcelJS:
    • Summary — one row per tile with current / target / status with conditional formatting (green / amber / red fill).
    • Data_{kpiId} — full time series per tile, overlays included.
    • Charts — slot for PNG charts (headless ECharts rendering comes next).
    • Metadata — definitions, formulas, units, precisions, sources.
    • Frozen header rows, workbook name {workspace}-{dashboard}-{YYYYMMDD}.xlsx.

Compare up to 3 KPIs side by side

Pin up to 3 KPIs from anywhere in the catalog and the Compare page shows them in columns with:

Governance, collaboration, and sharing

Once you bring up the backend ( apps/api ) these unlock automatically:

Plugin API for custom KPIs and data sources

POST /plugins/register accepts a Zod-validated manifest that can contribute:

Plugins are enabled per workspace; manifests are fetched and validated before activation.

PWA installable

A manifest ships out of the box so Chrome / Edge offer an Install option. Installed instances run in a standalone window — still 100 % web, no native shell.


Architecture at a glance

easykpi/
├─ apps/
│  ├─ web/        React 19 + Vite + TypeScript + Tailwind 4 + ECharts + Zustand
│  ├─ api/        Fastify 5 + Prisma 5 (SQLite locally / Postgres in prod) + ExcelJS
│  └─ forecast/   FastAPI + statsmodels (+ optional Prophet) sidecar
├─ packages/
│  └─ shared/     Zod schemas, TS types, formula registry, seeded benchmarks,
│                 driver DAGs, pure-JS Holt-Winters / anomalies / goal-seek,
│                 golden-value tests for all 95 formulas
├─ build-launcher.ps1  Rebuilds EasyKPI.exe — installs, builds, starts api +
│                      preview, opens the user's browser
└─ EasyKPI.exe        Windows single-click launcher

What changed from the original

The original repo was a single-page React demo: one 385-line App.jsx, inline styles, a JSON of 95 KPIs, and a manual-input calculator that rendered no charts. It has been rebuilt as the monorepo above while preserving every original formula byte-for-byte (95 golden-value tests pin the behavior). The Windows .exe single-click launch experience is kept, and a GitHub Pages deployment of the original static catalog remains linked at the top of this README for quick reference.


Getting started

Windows, one click

  1. Make sure Node.js 20+ is installed.
  2. Double-click EasyKPI.exe. On first launch it runs npm install --legacy-peer-deps, builds the web bundle, initialises the SQLite database, starts the Fastify API on :8787 and vite preview on :5173, and opens your default browser. Subsequent launches skip anything already done.

Any OS, manual

# Install dependencies
npm install --legacy-peer-deps

# Initialise the local SQLite database + seed the "local" workspace
cd apps/api && DATABASE_URL="file:./dev.db" npx prisma db push --skip-generate
DATABASE_URL="file:./dev.db" npx tsx prisma/seed.ts
cd ../..

# Start the API (terminal 1)
cd apps/api && DATABASE_URL="file:./dev.db" PORT=8787 npm run dev

# Start the web app (terminal 2)
cd apps/web && npm run dev

# (optional) Start the Python forecast sidecar (terminal 3)
cd apps/forecast
pip install -r requirements.txt
uvicorn main:app --port 8788

Open http://localhost:5173 — the web app proxies /api/* to http://localhost:8787.

Environment variables (apps/api/.env)

DATABASE_URL="file:./dev.db"              # or postgres://... for production
PORT=8787
ANTHROPIC_API_KEY=sk-ant-...              # optional — enables real AI narratives
CLERK_SECRET_KEY=...                       # optional — enables multi-user workspaces
CLERK_PUBLISHABLE_KEY=...                  # optional
PYTHON_FORECAST_URL=http://localhost:8788  # optional — Prophet sidecar
LLM_DAILY_CAP_USD=5                        # per-workspace daily spend cap

Without any of the optional variables the app still fully works — narratives return a deterministic stub, auth is single-user / local, and forecasts use the pure-JS Holt-Winters implementation.


API reference

All routes are workspace-scoped via the x-workspace-id header (drops into Clerk’s organisation model cleanly).

Endpoint Purpose
GET /health Liveness probe
GET /catalog/kpis, GET /catalog/kpis/:id, GET /catalog/count, GET /catalog/custom Catalog + per-workspace custom KPIs
POST /sql/query Server-side Postgres / BigQuery / Snowflake queries
POST /forecast Holt-Winters JS; proxies to Prophet sidecar when configured
POST /forecast/anomalies Z-score anomaly list
POST /forecast/goal-seek Formula inversion by bisection
POST /narrate Claude Sonnet / Opus narratives with caching + spend cap + stub fallback
POST /semantic/search Ranked KPI list for a natural-language question
POST /export/dashboard Multi-sheet dashboard workbook via ExcelJS
GET/POST/DELETE /dashboards[/:id] Dashboard CRUD (auto-writes audit events)
GET /audit Filterable audit log
GET/POST /comments Comments on KPIs and dashboard tiles with mentions
POST /permalinks, POST /permalinks/:token/revoke, GET /s/:token Shareable read-only links
GET/POST/DELETE /digests, POST /digests/:id/run Scheduled digest config + manual run
GET/POST/DELETE /plugins[/:id] Plugin registry

Testing

# Golden-value tests for all 95 formulas (the refactor safety net)
cd packages/shared && npx vitest run

# Strict typecheck across every workspace
cd packages/shared && npx tsc --noEmit
cd apps/web      && npx tsc --noEmit
cd apps/api      && npx tsc --noEmit

# Production web build
cd apps/web && npx vite build

# API smoke (with api running on :8787)
curl -s http://localhost:8787/health
curl -s http://localhost:8787/catalog/count
curl -s -X POST -H "Content-Type: application/json" \
  -d '{"query":"are we losing customers","topK":5}' \
  http://localhost:8787/semantic/search

Design notes


Roadmap (not yet shipped)