Skip to content

Get Started

Set up Bioloupe Forecasting locally and run your first forecast. This guide covers prerequisites, environment configuration, and a walkthrough of the main workflow.

You need the following installed before you begin.

ToolMinimum versionCheck with
Node.js22.xnode --version
pnpm10.6+pnpm --version
Gitany recentgit --version

The backend API (bioloupe-data-gov) must be running locally on port 3010 for data fetching to work. See the data-gov README for backend setup.

Warning: Never use npm for this project. The monorepo uses pnpm exclusively. The packageManager field in package.json enforces pnpm 10.6.5.

Clone the monorepo and install dependencies.

Terminal window
git clone git@github.com:bioloupe/bioloupe-monorepo.git
cd bioloupe-monorepo/bioloupe-forecasting
pnpm install

Copy the example environment file and adjust values if needed.

Terminal window
cp .env.example .env

The default .env.example contains:

Terminal window
# Data-gov API URL (statistics endpoints)
VITE_API_URL=http://localhost:3010
# Bioloupe client URL (for login redirect)
VITE_BIOLOUPE_URL=http://localhost:8080
# Feature flags
VITE_ENABLE_PRICING=false
VariablePurposeDefault
VITE_API_URLRails backend for statistics datahttp://localhost:3010
VITE_BIOLOUPE_URLBioloupe client for auth redirectshttp://localhost:8080
VITE_ENABLE_PRICINGToggle pricing featurefalse

Note: Production and PR-preview Cloudflare Pages deploys both point at the same Rails API — VITE_API_URL is environment-agnostic by design (no staging API exists). PR previews can therefore mutate live forecasting models. Forecasting CRUD mutations in src/hooks/useForecasting.ts override to retry: 0 to reduce duplicate-write blast radius. src/components/PreviewBuildBanner.tsx renders an amber warning at the top of preview builds (any *.forecasting.bioloupe.com host other than forecasting.bioloupe.com / www.forecasting.bioloupe.com) so users know their saves hit live data.

Tip: Vite automatically loads .env, .env.local (gitignored), and .env.production. Put personal overrides in .env.local to avoid accidental commits.

Terminal window
pnpm dev

Vite starts on port 3001 (as configured). Open the URL shown in terminal output. You must be authenticated — the app checks your session via /api/check_session using a JWT cookie (_bioloupe_jwt) from the Bioloupe client.

Warning: If the API server is not running, the session check times out after 10 seconds. You see "Connection timed out. Is the API server running?" and the login screen. Start the data-gov backend first.

Terminal window
pnpm build

This runs tsc -b for type checking followed by vite build. Output goes to dist/.

Terminal window
pnpm lint # check for issues
pnpm lint:fix # auto-fix issues
pnpm format # format all files

Biome handles both linting and formatting. The project uses 2-space indentation, double quotes, and semicolons.


Once the dev server is running and the backend is active, follow these steps.

The top bar shows geography and indication selectors. Pick a geography (e.g., “USA”) and an indication (e.g., “Breast Cancer”). The app loads reference data from /api/forecasting/statistics (gated to forecasting-ready diseases by the data-gov ReadinessChecker) and initializes the instance store with disease-specific defaults.

Domain context: A “geography” is a market region (USA, EU5, Japan, or custom). An “indication” is a disease (e.g., Breast Cancer, Multiple Myeloma). Each geo/indication combination has its own incidence data, stage mix, and therapy line configuration.

Scroll to the Configuration section. You see a patient-flow tree and three configuration areas:

  • Assumptions — launch price, market exclusivity years, molecule type (Biologic or Small Molecule), LoE date, annual net price change
  • Population — healthcare access, treatment rate, stage mix (for solid tumors), relapse rates
  • Therapy lines — each line shows transition rate, treatment rate, peak share inputs (launch order, best-in-class, delay vs. competition), launch date, and uptake speed

Fields show guidance indicators when they hold default values from the disease database. Change a value and the indicator disappears.

The Evolution section shows three editable time-series arrays across the projection window:

  • Incidence evolution — annual patient counts driven by growth rate and acceleration
  • Net price evolution — annual price change percentages
  • Erosion curves — post-LoE market share decay (biologic vs. small molecule profiles)

Edit any row to override the computed defaults. Growth rate changes cascade forward from the edit point.

The Model section displays a year-by-year table. Each row is a projection year. Columns show eligible patients, new patients, market share, net price, and revenue per therapy line. Totals aggregate across all selected lines and stage groups.

The Sales chart visualizes revenue from the Model table as a stacked bar chart. Each therapy line gets its own color. Switch chart palettes with the color selector in the header (Default, Corporate Blue, Vibrant, Earth Tones, or High Contrast).

Open the Monte Carlo section. Select which variables to randomize (launch price, peak share, months of therapy, healthcare access, treatment rate, stage mix percentages, relapse rates, and custom variables). Set min/max ranges and distribution type (triangular, normal, or uniform). Click Run to execute the simulation.

The chart shows the base-case model output against percentile bands (P10, P50, P90). The results table lists mean, median, and percentile values per year.

Tip: Default min/max ranges are computed as +/- 10% of the base value. Percentage-based variables are capped at 100. You can adjust these bounds before running.

The Tornado section runs one-at-a-time sensitivity on each selected variable for a target year. The chart ranks variables by their impact on total sales, showing high and low bounds as horizontal bars. Variables are sorted by total impact (ascending), so the most impactful variable appears at the top.

Open multiple scenario tabs using the ”+” button in the tab bar. Each tab gets its own independent Jotai store — configure different geographies, indications, or assumptions per tab. Click the “Compare” tab to see a side-by-side comparison of sales, Monte Carlo results, model totals, and tornado analysis across all selected scenarios. Each section has an Export dropdown (Image + CSV), and an “Export Report” button generates a full DOCX comparison report.

Click Save in the header toolbar. Name your model. The app serializes the full multi-scenario state (all tabs, overrides, selections, and context) as a versioned JSON snapshot and persists it to the backend via POST /api/forecasting. Load it later from the model selector. The unsaved-changes indicator (dirty state) tracks whether you have modifications since the last save.


ScriptCommandPurpose
devpnpm devStart Vite dev server
buildpnpm buildType-check and build for production
lintpnpm lintCheck code with Biome
lint:fixpnpm lint:fixAuto-fix lint issues
formatpnpm formatFormat code with Biome
testpnpm testRun Vitest unit tests once
test:watchpnpm test:watchVitest watch mode
test:coveragepnpm test:coverageRun tests with V8 coverage report (CI gate enforces 85% line coverage on the Phase-1 extracted-pure-math subset: constants.ts, distributions.ts, incidence-evolution.ts, transplant.ts — see vitest.config.ts)
previewpnpm previewPreview the production build locally

A Husky pre-commit hook delegates to lint-staged, which runs biome check --staged-files and vitest related --run on staged *.{ts,tsx,js,jsx} files — see CLAUDE.md and README.md for the full Testing & pre-commit guide.