ibcs-react

Getting started

Install ibcs-react, render your first IBCS chart, and learn how sizing and client rendering work.

Install the package, hand a component your numbers, and you get output drawn in the IBCS notation - scenario fills, impact-coloured variances and zero-baseline axes - with no chart wiring.

Install

npm install ibcs-react

ibcs-react ships ESM + CJS with types, built one file per module so your bundler drops what you don't import. The claim is enforced, not aspirational: CI bundles a KpiCard-only fixture against the published output and fails if it exceeds ~4 KB gzip or drags another component along.

Peer dependencies

React and React DOM are peer dependencies - the library uses your app's copy rather than bundling its own. Any React 18 or newer works (18 and 19 are both fine).

npm install react react-dom

There are no other runtime dependencies: charts are hand-rolled inline SVG, so there is no D3, no charting engine and nothing to configure.

The one-data-model idea

The whole library is built on a single model: values keyed by scenario - AC (actual), PY (previous year), PL (plan) and FC (forecast). A StatementTable, a VarianceColumnChart and a KpiCard are just different views over that same shape. Compute your figures once and reuse them everywhere - you never reshape data per component.

Components never fetch. You bring the numbers (from your ERP, an API, static JSON); the library handles the notation.

Your first dashboard

A KPI card and a statement table, both driven by the same scenario-keyed values:

Revenue
€30.1M+4.5M+17.6%vs PY
 PYACΔPYΔPY%
Product revenue16.1M17.2M+1.1M+6.8
Service revenue9.5M12.9M+3.4M+35.8
=Revenue25.6M30.1M+4.5M+17.6
−Cost of goods sold8.4M9.7M+1.3M+15.5
=Gross margin17.2M20.4M+3.2M+18.6
import { KpiCard, StatementTable } from "ibcs-react";

// ONE data model - values keyed by scenario (AC/PY/PL/FC) - feeds every
// component. Nothing here fetches; you bring the data.
const statement = [
  { id: "rev-product", label: "Product revenue", flow: "add", values: { AC: 17.2e6, PY: 16.1e6 } },
  { id: "rev-service", label: "Service revenue", flow: "add", values: { AC: 12.9e6, PY: 9.5e6 } },
  { id: "revenue", label: "Revenue", flow: "result", values: { AC: 30.1e6, PY: 25.6e6 } },
  {
    id: "cogs",
    label: "Cost of goods sold",
    flow: "subtract",
    higherIsBetter: false,
    values: { AC: 9.7e6, PY: 8.4e6 },
  },
  { id: "gross-margin", label: "Gross margin", flow: "result", values: { AC: 20.4e6, PY: 17.2e6 } },
];

export function Dashboard() {
  return (
    <>
      <KpiCard
        label="Revenue"
        values={{ AC: 30.1e6, PY: 25.6e6 }}
        comparisons={["PY"]}
        format={{ compact: true, decimals: 1, currency: "€" }}
      />
      <StatementTable lines={statement} format={{ compact: true, decimals: 1 }} />
    </>
  );
}

Sizing

Charts draw an SVG at an explicit pixel size: pass width and height (every chart has a sensible default - VarianceColumnChart is 560 × 320, WaterfallChart 640 × 360, TrendChart 720 × 360). Labels, ticks and bar widths are laid out for exactly that box, which is what keeps a chart readable in print.

<VarianceColumnChart data={data} width={620} height={320} />

For a chart that follows its container, wrap it in ChartBox - one sizing primitive with fit modes ("scale", "fixed", "contain", "fill"), alignment, padding and scroll behaviour. It re-renders the chart at the resolved pixel size instead of scaling a bitmap, so text and strokes stay crisp:

import { ChartBox, TrendChart } from "ibcs-react";

// Scale with the space, but hold a readable 680px and scroll below that.
<ChartBox width={760} height={300} fit="scale" minWidth={680}>
  {(w, h) => <TrendChart width={w} height={h} data={data} />}
</ChartBox>;

See Interaction & data for the full fit/align/scroll options. (ChartFrame still exists but is deprecated - ChartBox covers it.)

"use client" and server components

The package entry ships its own "use client" directive, so a React Server Component can import and render a chart directly - you do not need to add a "use client" file of your own just to place a VarianceColumnChart on a server-rendered page:

// app/page.tsx - a server component
import { VarianceColumnChart } from "ibcs-react";

export default function Page() {
  return <VarianceColumnChart data={data} width={620} height={320} />;
}

You do need your own "use client" component when your code holds state or handlers around the chart - a scenario toggle, an onSelect drill-down, a theme switcher. Rendering itself is SSR-safe: the markup is plain SVG, and the optional tooltip only appears on the client.

Where to next

  • Data model - the exact shape of StatementLine, TrendDatum and friends, plus the statement adapters.
  • IBCS & ISO 24896 - what the notation means and why a variance is red when it grows.
  • Theming - token presets, IbcsThemeProvider and per-component overrides.
  • Conformance - lint a config against the IBCS notation rules the library implements.
  • Components - a page each, with live examples, code and a props table generated from the source types.
  • Playground - configure charts live in the browser.

Project status

ibcs-react is in active development. It is an independent implementation of the IBCS notation described by ISO 24896 - not certified by, affiliated with or endorsed by IBCS or ISO. Open gaps and feedback are tracked on GitHub.

ibcs-react is an independent open-source library and is not affiliated with, certified by, or endorsed by the IBCS Association or ISO. It follows the IBCS® notation rules (the basis of ISO 24896); IBCS® is a registered trademark of the IBCS Association.

On this page