Overview
Pension Tracker is a small Next.js tool that projects how a UK pension pot grows from age 25 to retirement, and how it depletes afterwards under a chosen drawdown. You put in desired retirement income, employer and personal monthly contributions, retirement age, and any existing pots, and it charts both halves of the journey — accumulation and drawdown — rather than just giving you a single "you'll have £X" number.
The problem
Most pension calculators either oversimplify (a single compound-interest projection with no drawdown modelling) or bury the maths in a PDF-style report you can't interrogate. I wanted something that treated growth and drawdown as two connected but distinct calculations — the pot doesn't just grow to a number and stop, it has to actually last through retirement at the income you've said you want, and seeing both curves side by side makes it obvious whether a plan is realistic or not.
What I built
A tested calculation engine, separate from the UI
The core logic lives in pensionCalculator.ts, covering contribution growth with compound interest at an annual rate, the required pot size for a given desired income, and how existing pension pots factor into the projection. It's covered by its own unit test suite independent of the component tests — contribution growth, required-pot maths, and the impact of existing pots are all tested in isolation from the form and chart rendering, which matters because a calculation bug here is a wrong answer, not a cosmetic one.
Two connected charts
The projected growth chart shows the pot compounding annually at 4.9% from age 25 to retirement, accounting for existing pots contributed at setup. The post-retirement drawdown chart picks up from there, simulating the pot depleting as the user's desired annual income is withdrawn, out to age 81. Building these as two charts sharing the same underlying pot value at the handoff point (age at retirement) rather than as two disconnected calculators was the actual design decision — it's what makes the tool answer "will this plan actually work" rather than just "how big will my pot be."
A modular form
The input form — desired income, employer and personal contributions, retirement age, and a repeatable "existing pension pots" section for anyone with more than one pot from previous jobs — is built from reusable TextInput and Button components rather than one large form component. Multiple existing pots is a real scenario for most people who've had more than one job, so the form needed to support adding and removing pot entries rather than assuming a single figure.
Component and logic tests together
Alongside the calculation tests, there's coverage for Button (all variants), TextInput, and PensionForm — form logic, input changes, adding and removing pots, and submission. Testing the form's add/remove-pot interaction mattered more than it might seem for a "simple" calculator; it's the one piece of genuinely stateful UI logic in an otherwise mostly-derived app.
Engineering decisions
Recharts over a hand-rolled SVG chart
For two fairly standard line charts, Recharts gave sensible defaults (axes, tooltips, responsive sizing) without the project needing to own chart-rendering code. For a personal tool like this, the calculation engine is where the actual value and the actual bugs live — the chart library is infrastructure, and reaching for a well-tested one rather than building from scratch kept effort pointed at the part that mattered.
Separating calculation from presentation
Keeping pensionCalculator.ts free of any React or chart-specific code meant it could be unit tested directly, with plain numbers in and plain numbers out, rather than needing to render components to verify the maths. That separation is a small thing on a project this size, but it's the difference between "does the chart look about right" and "is this number provably correct."
Stack
| Layer | Choice |
|---|---|
| Framework | Next.js (App Router) · TypeScript |
| Styling | Tailwind CSS |
| Charts | Recharts |
| Testing | Jest · React Testing Library |
Reflections
This is a small project, but it's a clean example of the habit I try to carry into everything: keep the part that has to be correct (the pension maths) separate from and independently tested from the part that has to look right (the form and charts). It also reinforced something obvious in hindsight — a projection tool is only useful if it shows the whole picture. A pot that grows impressively but runs out eight years into retirement is a plan that's failed, and you only see that if growth and drawdown are on the same page.