Skip to content

tuangatech/retirement-planner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

58 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Retirement Planning Simulator

The Honest Retirement Calculator

A privacy-first, Monte Carlo simulation-based retirement planning tool that helps individuals determine if their retirement plan will work. Built with transparency and statistical accuracy in mind, this tool honestly discloses its limitations rather than creating false confidence.

CI License: MIT TypeScript React PRs welcome

๐Ÿ‘‰ Try the live demo โ€” no install, runs entirely in your browser


๐ŸŽฏ Product Summary

"Tell me what you'll have AT retirement, and I'll tell you if it will last."

This tool focuses exclusively on the retirement phaseโ€”no pre-retirement accumulation modeling. Users input their projected retirement balances, and the simulator models whether those assets will sustain them through retirement.

Key Features

  • ๐ŸŽฒ Monte Carlo Simulation โ€” 10,000 runs with randomized market returns
  • ๐Ÿ“Š Probabilistic Results โ€” success rate and outcome distribution (10th/50th/90th percentiles)
  • ๐Ÿ’ฐ HSA Integration โ€” tax-free healthcare coverage, with age-65+ flexibility
  • ๐Ÿฅ Phase-Based Spending โ€” Go-Go, Slow-Go, and No-Go years
  • ๐Ÿ’ณ Multiple Income Sources โ€” Social Security (with earnings test), pensions, part-time work, rental
  • ๐Ÿ”’ Privacy-First โ€” no server, no accounts, no tracking; everything runs in your browser
  • ๐Ÿ’พ Scenario Management โ€” save and compare scenarios in browser localStorage
  • ๐Ÿ“ˆ Rich Visualizations โ€” interactive charts (Recharts)
  • ๐Ÿงพ Exportable & Verifiable โ€” CSV export plus a JSON bundle checked by scripts/verify_plan.py
  • โš ๏ธ Honest Limitations โ€” mandatory disclosure of what the tool does NOT model

Target Audience

Early retirees, the FIRE community, and DIY planners who want transparent, statistically honest projections.

Scope & Limitations

Read this before trusting a number. The app's Disclosures tab shows the same list with your own figures filled in โ€” none of it is buried in a footnote.

What it models โ€” US federal taxes for single and married filing jointly filers ยท Social Security (claiming age, COLA, earnings test, provisional-income taxability) ยท RMDs from age 75 ยท Medicare premiums and IRMAA ยท pre-Medicare healthcare ยท HSA (incl. age-65+ flexibility) ยท pensions, part-time work, and rental income ยท phase-based spending (Go-Go / Slow-Go / No-Go) ยท three withdrawal strategies, including gap-year Roth conversions.

What it deliberately does not model โ€” pre-retirement accumulation ยท state income tax ยท ACA subsidies for pre-Medicare coverage ยท long-term care (often the largest single retirement risk) ยท the survivor's penalty for couples ยท per-spouse accounts (couples' balances are pooled) ยท variable inflation ยท dynamic spending guardrails ยท fat-tail crashes ยท fees and transaction costs ยท home equity, mortgages, and property taxes.

Key simplifications โ€” one marginal rate above the standard deduction rather than the full 10โ€“37% brackets ยท long-term capital gains taxed at that same flat rate (no 0/15/20% brackets) ยท fixed life expectancy, not a mortality distribution ยท all accounts share one market shock per year (perfectly correlated) ยท annual returns capped at ยฑ50% ยท IRMAA estimated by you rather than derived from MAGI.

Several of these gaps are open, well-scoped contribution opportunities โ€” see CONTRIBUTING.md.


๐Ÿ› ๏ธ Tech Stack

  • React 18 + TypeScript 5 โ€” UI and type-safe logic
  • Vite 5 โ€” build tool and dev server
  • React Router 6 โ€” client-side routing (Landing โ†’ Wizard โ†’ Results โ†’ Scenarios/Compare)
  • Tailwind CSS 3 + shadcn/ui (Radix UI primitives) โ€” styling and components
  • Recharts 2 โ€” charts ยท Lucide โ€” icons
  • React Context API โ€” global state (no Redux)
  • Web Workers โ€” Monte Carlo runs off the main thread
  • localStorage โ€” scenario persistence (inputs only, not results)
  • Vitest โ€” unit tests for the calculation engine

๐Ÿš€ Getting Started

Just want to try it? Use the live demo โ€” no setup required. The steps below are only for running it locally.

Prerequisites

  • Node.js v18+ and npm v9+
  • A modern browser with Web Worker support (Chrome 90+, Firefox 88+, Safari 14+, Edge 90+)

Installation

git clone https://github.com/tuangatech/retirement-planner.git
cd retirement-planner
npm install
npm run dev

Then open http://localhost:5175.

Available Scripts

npm run dev          # Start Vite dev server (hot reload) on port 5175
npm run build        # Type-check + production build to ./dist
npm run preview      # Serve the production build locally
npm test             # Run the Vitest unit-test suite once
npm run test:watch   # Vitest in watch mode (re-runs on change)
npm run lint         # ESLint (flat config); errors block, style nits are warnings
npm run type-check   # TypeScript check, no emit

Testing: unit tests (Vitest) cover the pure calculation modules in src/lib/calculations/ โ€” taxes, RMDs, Social Security, HSA, withdrawals, the seeded RNG, and the depletion/success metric. They're the fast regression net; the JSON export + verify_plan.py workflow below is the end-to-end cross-check. Test files live next to the code they cover as *.test.ts.


โœ… Verifying the Calculations

Every simulation can be independently re-checked against a Python re-implementation of the expected-value formulas.

  1. Run a simulation, go to the Annual Breakdown tab, and click JSON to download retirement-verification-<yyyymmdd-hhmm>.json (contains all inputs, settings, and the p10/p50/p90 year-by-year projections).
  2. Move that file into the scripts/ folder.
  3. Run the verifier (it auto-picks the newest bundle in scripts/):
python3 scripts/verify_plan.py                    # newest bundle, median (p50)
python3 scripts/verify_plan.py --percentile p10   # check the worst-case run
python3 scripts/verify_plan.py --json path/to/file.json --tolerance 0.03

It re-derives income, expenses, healthcare premiums/out-of-pocket, taxes, and the cash-flow identity from the inputs, and exits non-zero if any deterministic check fails. Downloaded bundles are git-ignored. See docs/7-technical-implementation.md ยง4.2 for details.


๐Ÿ“ฆ Project Structure

retirement-planner/
โ”œโ”€โ”€ .github/               # CI workflow, issue/PR templates, Dependabot
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ components/        # UI: ui/ (shadcn), common/, wizard/, results/,
โ”‚   โ”‚                      #     scenarios/, comparison/
โ”‚   โ”œโ”€โ”€ contexts/          # InputsContext (inputs), ResultsContext (worker + results)
โ”‚   โ”œโ”€โ”€ lib/
โ”‚   โ”‚   โ”œโ”€โ”€ calculations/  # Calculation engine (see below)
โ”‚   โ”‚   โ”œโ”€โ”€ storage/       # localStorage scenario management
โ”‚   โ”‚   โ”œโ”€โ”€ exportVerification.ts  # JSON verification bundle
โ”‚   โ”‚   โ”œโ”€โ”€ constants.ts   # Default values, RMD table, SS factors
โ”‚   โ”‚   โ””โ”€โ”€ utils.ts, format.ts
โ”‚   โ”œโ”€โ”€ workers/           # monte-carlo.worker.ts (simulation engine)
โ”‚   โ”œโ”€โ”€ pages/             # LandingPage, WizardPage, ResultsPage,
โ”‚   โ”‚                      # ScenariosPage, ComparisonPage
โ”‚   โ”œโ”€โ”€ types/index.ts     # All TypeScript interfaces
โ”‚   โ”œโ”€โ”€ App.tsx, main.tsx, index.css
โ”œโ”€โ”€ scripts/               # verify_plan.py + downloaded verification bundles
โ”œโ”€โ”€ docs/                  # requirements, system-design, technical-implementation, tax-model
โ”œโ”€โ”€ public/                # Static assets
โ”œโ”€โ”€ CONTRIBUTING.md, CODE_OF_CONDUCT.md, SECURITY.md, LICENSE
โ”œโ”€โ”€ vite.config.ts, tsconfig.json, tailwind.config.js, components.json
โ””โ”€โ”€ package.json

Routes: / (landing) โ†’ /wizard/:step (4-step wizard) โ†’ /results (5 tabs: Summary, Monte Carlo, Cash Flow, Annual Breakdown, Disclosures); plus /scenarios and /compare.


๐Ÿงฎ Calculation Engine

Located in src/lib/calculations/ โ€” independent, pure, unit-testable modules:

random.ts            Seeded RNG (Mulberry32) + Box-Muller normal returns
rmd.ts               Required Minimum Distributions (IRS Uniform Lifetime Table)
socialSecurity.ts    Claiming-age adjustment, COLA, earnings test
income.ts            Pensions, part-time work, rental income
expenses.ts          Phase-based spending + healthcare (pre-Medicare & Medicare)
taxes.ts             Effective-rate model + iterative gross-up
withdrawals.ts       Withdrawal sequencing, RMD enforcement, HSA-first
hsa.ts               HSA tax-advantaged withdrawal logic
yearlyProjection.ts  Orchestrates all modules for one year

The monte-carlo.worker.ts worker runs 10,000 full simulations and aggregates success rate, percentiles, and the p10/p50/p90 projections. A seeded PRNG makes results reproducible.

Performance: 10,000 runs complete in a few seconds.


๐Ÿšข Deployment (Vercel)

The app is a static SPAโ€”no backend or environment variables.

  1. Import the GitHub repo into Vercel once. Vercel auto-detects the Vite preset and runs the build for you (output dist) โ€” you don't build locally.
  2. Every push to main triggers a production deploy; other branches and PRs get preview deploys. That's the whole workflowโ€”just push.

A vercel.json at the repo root rewrites all paths to index.html, so deep links and page refreshes (e.g. /results) don't 404 under the app's client-side routing. It's already includedโ€”no action needed.

Building locally is optional โ€” Vercel builds on its servers. If you want to sanity-check a production bundle before pushing, npm run build (and npm run preview) are available, but they aren't part of the deploy step.


๐Ÿ”’ Privacy & Data

All calculations run in your browserโ€”no server, no accounts, no tracking, no cookies. Scenarios are saved to localStorage (inputs only; results are recalculated on load because they're too large to store).

โš ๏ธ Don't use on a shared/public computerโ€”anyone with browser access can view saved scenarios.

Configuration lives in vite.config.ts, tsconfig.json, tailwind.config.js, and components.json; no .env is required.


๐Ÿ“– Documentation

For contributors: CONTRIBUTING.md ยท CODE_OF_CONDUCT.md ยท SECURITY.md

Key Design Decisions

  1. No pre-retirement modeling โ€” focuses only on the retirement phase.
  2. Simplified tax model โ€” single effective rate rather than full brackets.
  3. Mandatory assumptions panel โ€” honest disclosure of limitations.
  4. localStorage only โ€” no cloud sync keeps it simple and private.
  5. Web Workers โ€” keep the UI responsive during 2โ€“10s simulations.

๐Ÿค Contributing

Contributions are welcome โ€” including from people who don't write code.

  • Use it and report what's wrong. Run the live demo with a plausible plan and file anything confusing or incorrect.
  • Check the math. Export the JSON bundle and run python3 scripts/verify_plan.py. If it disagrees with the app, that's a great bug report.
  • Challenge an assumption. If you know the tax, Medicare, or Social Security rules better than the code does, cite the source and we'll fix it or document the simplification.
  • Close a known gap. State income tax, ACA subsidies, and the survivor's penalty are all documented, unbuilt, and well-scoped.

Read CONTRIBUTING.md first โ€” the engine has hard invariants (seeded RNG, exactly two rng() calls per simulated year, pure calculation modules) that are easy to break by accident. Issues labeled good first issue are safe entry points.

๐Ÿ”’ Never post your real financial data in an issue. Use rounded or synthetic numbers โ€” the exported JSON bundle contains every figure you entered.

By participating you agree to the Code of Conduct.


๐Ÿ“ License

MIT โ€” see LICENSE.

Educational projections only; not financial, tax, legal, or investment advice. The software is provided "as is", without warranty of any kind. Consult a qualified professional before making retirement decisions.


Made with โค๏ธ for the FIRE community

Releases

Contributors

Languages