KQ-718 · NEST/EGG

Nest Egg

A chart of a balance compounding over the years: a principal plus a monthly contribution, compounded monthly at the chosen rate. On mount the curve draws itself from year zero with pathLength on glide over a dashed line of the contributions alone, so the gap between them — the growth — is the picture. The plot is a slider: pressing or dragging reads the value at the nearest year, a cursor and a dot travelling to it on snap while a callout above rolls the year's balance with the contributed and growth split beneath. The rate chips morph the path on glide — every path has the same point count, so the curve bends rather than blinks — against a vertical scale fixed to the highest offered rate, so a higher rate visibly lifts the curve. Arrows step a year, Page keys five, Home and End reach the ends, and a status line announces the settled year, never every year a drag passes through.

KQ-718 · NEST/EGG
Nest egg$2,500 in, $200 a month, 30 years
Year 20, $88,988, contributed $50,500, growth $38,488

Year 20 · 5% · $88,988 · Growth $38,488

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/nest-egg

Props

principal
number
default 0
The opening balance.
monthly
number
default
The monthly contribution, compounded monthly at the chosen rate.
years
number
default 30
The horizon; the plot has a point per year and the slider runs from 0 to here.
rates
number[]
default [3, 5, 7, 9]
The rate chips in percent per year; the vertical scale fits the highest so a higher rate lifts the curve rather than rescaling it.
rate / defaultRate
number
default the middle chip
Controlled or initial annual rate in percent.
onRateChange
(rate: number) => void
default
Fires from the chip press or key.
year / defaultYear
number
default years
Controlled or initial scrub position in years.
onYearChange
(year: number) => void
default
Fires from the pointer or key that moved the cursor.
format
(value: number) => string
default Intl.NumberFormat("en-US", { style: "currency", currency: "USD", maximumFractionDigits: 0 })
Formats every amount. The default pins an explicit locale so server and client agree.
label
string
default
Names the chart; printed as the heading and read as the slider's label.