A Next.js 15 app for defining, visualizing, and exporting insulin time–activity profiles.
This tool lets you work with insulin curves in a dose-normalized, time-indexed format:
t (minutes) → fraction_of_dose_active (0–1)
It’s designed so humans can edit the curve visually and LLMs/tools can read/write the JSON format consistently.
⚠️ Not medical advice: this is a modeling/authoring tool for curves — it does not calculate patient doses, glucose, or clinical recommendations.
- What This Tool Models
- Key Concepts
- Features
- Tech Stack
- Getting Started
- Data Model
- Using the App
- Import/Export
- Normalization
- Extending With New Insulin Types
- Conventions for LLMs
- Notes & Limitations
Insulin products have different time–action characteristics (onset, peak, duration). This app represents those as a discretized time–activity function: for each timepoint, what fraction of the dose is “active” or “expressed” in the model.
- Keys: minutes since administration (
"0","5","10", …) - Values: unitless fraction (
0–1) representing % of total modeled effect at that timepoint
Example:
{
"0": 0.025,
"5": 0.05,
"10": 0.075,
"15": 0.1,
...
"590": 0.001,
"595": 0
}Interpretation:
- At 90 minutes, if the entry is
"90": 0.47, that means 47% of the modeled effect is present at that time in this profile. - The whole series describes the curve shape: rise → peak → tail.
- The app can normalize the series so the total area (sum of values × interval) represents 1.0 (100%), making curves comparable.
This is intentionally dose-normalized so you can reuse the same shape for different absolute doses.
- Time–activity profile: sequence of (time, fraction) pairs.
- Dose-normalized: values are proportions of effect, not actual units.
- Discretized: we store fixed time steps (usually 5 minutes).
- Classification: each JSON belongs to an insulin “class” (IV bolus, rapid, short, intermediate, long/basal).
- Editable: points can be dragged; segments can be adjusted.
- Interactive canvas curve editor
Drag points to refine onset, peak, and tail phases. - Multiple insulin types
Presets for IV bolus, rapid, short, intermediate, and long-acting/basal. - Parameter controls
Adjust segments, radius/curvature, and selection behavior. - Normalization utilities
Ensure total activity sums correctly so curves are PK-consistent. - Import/Export
Load previously saved JSON curves or export the one you just designed. - Modern UI
Built with Tailwind CSS and React 19, responsive and keyboard-friendly.
- Next.js 15 (App Router)
- React 19
- Tailwind CSS
- Canvas-based visualization for the curve editor
- Node.js 18+ runtime expected for local dev
- Node.js 18+
- npm or yarn
npm installnpm run devOpen: http://localhost:3000
npm run build
npm startThis is the most important part for both developers and LLMs.
type TimeActivityProfile = {
[minute: string]: number; // 0–1 fraction of dose active
};- Keys: strings of integer minutes (
"0","5","10", …).
Typically 5-minute steps, but the UI may allow other granularities. - Values:
numberbetween0and1. This is a relative activity value.
{
"0": 0.025,
"5": 0.05,
"10": 0.075,
"15": 0.1,
"20": 0.125,
"25": 0.15,
...
"400": 0.1,
...
"595": 0
}- Think of this as a lookup table: “At minute
t, return the relative effect.” - The totality of points defines the insulin’s time–action curve.
- The app can normalize this so that the sum of all points (properly integrated) equals 1.0 (100%).
- Easy for LLMs to generate.
- Easy to diff/version.
- Easy to import/export.
- Easy to plot.
-
Select an insulin type
From the datasets/presets panel, choose something like Rapid or Long. This loads a baseline profile. -
View the curve
The canvas shows time on the X-axis (minutes) and relative activity on the Y-axis (0–1). -
Edit points
Click/drag points to change the shape.- Use X/Y lock checkboxes to constrain to horizontal/vertical changes.
- Use segment/radius controls to smooth or refine certain regions (e.g. peak).
-
Normalize (recommended)
After large edits, click the “Normalize” (or equivalent) action so the resulting curve still represents 100% of the effect. -
Export
When you’re happy, export the JSON. This gives you exactly the structure shown above. -
Import
If you have an older curve or one generated by an LLM, import it and the app will visualize it.
- Produces a JSON object in the shape described above.
- Intended to be round-trippable (export → edit → import).
- Expects a JSON object whose keys are minute strings and values are numbers between 0 and 1.
- If values don’t sum to 1.0 (or close), you can run Normalize inside the app.
Example imported JSON:
{
"0": 0,
"5": 0.02,
"10": 0.08,
"15": 0.2,
"20": 0.3,
"25": 0.25,
"30": 0.1,
"35": 0.05,
"40": 0
}Because this is meant to represent dose-normalized activity over time, normalization matters.
What normalization does:
- Sums/integrates the current values over time.
- Scales them so that the total represents 1.0 (100%).
- Writes the scaled values back to the profile.
Why normalize?
- To compare two different insulin classes on equal footing.
- To feed these curves into downstream logic that assumes 100% total effect.
- To avoid accidental “over-100%” curves created by dragging points.
If you want to add a new preset (e.g. “Ultra-rapid” or “NPH-like tail”), the pattern is:
- Create a new JSON in the same format:
{ "0": 0, "5": 0.04, "10": 0.1, ... "240": 0 } - Add it to whatever dataset/config file the UI is reading from (often a
datasets.ts/insulinPresets.tsstyle file). - Give it:
- a label (“Ultra rapid SC”)
- a classification (rapid / short / intermediate / long / IV bolus)
- an optional description (“Short onset, high early peak, fast decline”)
- Test it by loading it in the UI and normalizing.
If you are an LLM or building an agent that emits one of these profiles, follow these rules:
- Always produce valid JSON with double quotes.
- Keys should be minute strings in ascending order:
"0","5","10", …
If you don’t know the app’s interval, default to 5 minutes. - Values must be numbers between 0 and 1.
- Try to produce a single peak unless modeling biphasic insulins.
- After emitting, you may add a short note: “Run Normalize in the UI.”
- Do not add extra top-level keys — the app expects a flat object.
- If asked for “long-acting/basal,” produce a low, broad curve with long tail.
- If asked for “IV bolus,” produce a very fast rise and fast decline.
Example LLM-friendly output:
{
"0": 0.0,
"5": 0.12,
"10": 0.25,
"15": 0.3,
"20": 0.2,
"25": 0.08,
"30": 0.03,
"35": 0.015,
"40": 0.0
}Then the user can normalize in the app.
- This is a curve-authoring tool, not a PK engine and not a dosing tool.
- Values represent relative pharmacologic effect (or activity), not plasma concentration.
- Real insulin PK/PD is affected by route, site, temperature, patient factors, etc. This tool is intentionally simpler — it gives you a consistent data shape for apps/simulators.
- You edit insulin time–activity curves visually.
- The app stores them as
minute -> fraction_of_dose_active. - You can normalize, import, and export.
- It’s all built on Next.js 15 + React 19 + Tailwind.
- It’s safe for LLMs to generate data for it if they follow the shape above.