Adjust model assumptions, pin a baseline, and compare calculated metrics and projection data in a chart and table.
A small growth model
Change assumptions. Compare against a pinned baseline.
Drag the ruler or use arrow keys. Shift slows; Alt accelerates.
Drag the ruler or use arrow keys. Shift slows; Alt accelerates.
Drag the ruler or use arrow keys. Shift slows; Alt accelerates.
| Period | Current | Baseline |
|---|---|---|
| Month 1 | 2880.00 | — |
| Month 2 | 3024.00 | — |
| Month 3 | 3175.00 | — |
| Month 4 | 3334.00 | — |
| Month 5 | 3501.00 | — |
| Month 6 | 3676.00 | — |
Illustrative arithmetic supplied by the demo, not a forecast.
pnpm dlx shadcn@latest add @latheui/scenario-workbenchPart of Lathe Pro. Set up your project once with your license key: npx latheui init --key <key>. See Lathe Pro.
Scenario Workbench is part of Lathe Pro
The preview is live and free to try. The source, the install and every assembly come with Pro: $79 once, with lifetime updates.
Depends on
| Prop | Type | Default | Description |
|---|---|---|---|
| title* (required) | string | — | Visible heading and chart label. |
| inputs* (required) | readonly ScenarioInput[] | — | Unique key, label, finite min/max, defaultValue and optional step for each assumption. |
| calculate* (required) | (values: Record<string, number>) => ScenarioResult | — | Pure synchronous application model returning metrics and uniquely labelled points. Errors are shown without discarding assumptions. |
| value / defaultValue | Record<string, number> | input defaults (defaultValue) | Controlled or initial canonical assumption values. |
| onValueChange | (values: Record<string, number>) => void | — | Receives changed assumptions. |
| disabled | boolean | false | Disable assumptions and baseline actions. |
| className | string | — | Classes for the section. |
Replace the demo data and callbacks with your application. Honor AbortSignal in asynchronous callbacks so cancellation also stops transport work.
"use client"
import { ScenarioWorkbench, type ScenarioResult } from "@/components/scenario-workbench"
const inputs = [{ key: "customers", label: "Starting customers", min: 10, max: 1000, defaultValue: 120, step: 10 }, { key: "growth", label: "Monthly growth (%)", min: 0, max: 25, defaultValue: 5 }, { key: "price", label: "Price per month", min: 1, max: 100, defaultValue: 24 }]
function calculate(values: Record<string, number>): ScenarioResult {
const points = Array.from({ length: 6 }, (_, index) => ({ label: "Month " + (index + 1), value: Math.round(values.customers * (1 + values.growth / 100) ** index * values.price) }))
return { metrics: [{ key: "revenue", label: "Month six revenue", value: points[5].value }, { key: "customers", label: "Month six customers", value: Math.round(points[5].value / values.price) }], points }
}
export default function ScenarioDemo() { return <div className="w-full max-w-3xl"><ScenarioWorkbench title="A small growth model" inputs={inputs} calculate={calculate} /><p className="mt-3 text-xs text-muted-foreground">Illustrative arithmetic supplied by the demo, not a forecast.</p></div> }