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.
๐ Try the live demo โ no install, runs entirely in your browser
"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.
- ๐ฒ 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
Early retirees, the FIRE community, and DIY planners who want transparent, statistically honest projections.
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.
- 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
Just want to try it? Use the live demo โ no setup required. The steps below are only for running it locally.
- Node.js v18+ and npm v9+
- A modern browser with Web Worker support (Chrome 90+, Firefox 88+, Safari 14+, Edge 90+)
git clone https://github.com/tuangatech/retirement-planner.git
cd retirement-planner
npm install
npm run devThen open http://localhost:5175.
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 emitTesting: 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.pyworkflow below is the end-to-end cross-check. Test files live next to the code they cover as*.test.ts.
Every simulation can be independently re-checked against a Python re-implementation of the expected-value formulas.
- 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). - Move that file into the
scripts/folder. - 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.03It 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.
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.
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.
The app is a static SPAโno backend or environment variables.
- 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. - Every push to
maintriggers 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(andnpm run preview) are available, but they aren't part of the deploy step.
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).
Configuration lives in vite.config.ts, tsconfig.json, tailwind.config.js, and components.json; no .env is required.
- 1-requirements.md โ product requirements
- 2-tax-model.md โ tax logic, constants/sources, and MFJ roadmap
- 3-withdrawal-strategy.md โ withdrawal order and tax-efficiency suggestions
- 4-married-filing-jointly.md โ married-filing-jointly (couples) model and roadmap
- 5- โ reserved for the per-state tax model (FL/TX/GA)
- 6-system-design.md โ architecture and design
- 7-technical-implementation.md โ implementation guide (incl. verification workflow)
For contributors: CONTRIBUTING.md ยท CODE_OF_CONDUCT.md ยท SECURITY.md
- No pre-retirement modeling โ focuses only on the retirement phase.
- Simplified tax model โ single effective rate rather than full brackets.
- Mandatory assumptions panel โ honest disclosure of limitations.
- localStorage only โ no cloud sync keeps it simple and private.
- Web Workers โ keep the UI responsive during 2โ10s simulations.
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.
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