RentOrBuy
A buy-vs-rent and house-hacking simulator
Problem
Most buy-vs-rent calculators break at least one of three fairness rules. Both paths should start with the same cash. Both should spend the same monthly budget, with the cheaper path investing the difference. And selling costs should count against the house.
Approach
A pure-function finance engine with no React or DOM code: mortgage, comparison, Monte Carlo with a seeded random generator and correlated housing and stock draws, house hacking, tax, qualification, affordability, net worth and sensitivity. The UI is Next.js 15, React 19, shadcn/ui and Recharts. Monte Carlo runs in a Web Worker, Zod validates every boundary, scenarios save to IndexedDB, and share links encode only what differs from the defaults. An edge route fills in ZIP-code defaults from Census ACS data.
Process
5 dated steps, from the project’s history
-
Engine and a 13-section dashboard
The first commit had the whole finance engine, its tests, and 13 dashboard sections, from buy-vs-rent to a "learn" page.
-
One page
Collapsed the sections into a single calculator page.
-
Fewer, faster controls
Deleted most of the separate sections in favor of one calculator plus saved scenarios. Sliders now update a trimmed live result while charts wait, Monte Carlo moved to a worker, and share links got shorter.
-
Built for thumbs
Stacked the affordability gauges on phones and turned info hovers into tap-to-open popovers, because on a phone a hover tooltip vanished on the same tap that opened it.
-
Horizon, refinance, ZIP lookup
Added sell-in-N-years and refinance what-ifs, ZIP-code market defaults, a light and dark toggle, and a swipeable chart carousel.
Results
Live on Vercel. CI runs typecheck, unit tests, lint and a production build on every push and pull request.
Lesson
My first version had 13 sections; two days later it was one calculator and a results panel. Keeping the maths separate from the UI meant I could rebuild the interface without touching the engine or its tests.