1
0 Comments

Building a Modern Mortgage Calculator: A Developer's Journey

As a developer, I've always been frustrated by the mortgage
calculators available online. Most assume you have a single mortgage with a
fixed rate for the entire term, but real-world mortgages are far more complex.
That's why I decided to build a comprehensive mortgage repayment calculator that
actually reflects how modern mortgages work.

In this first blogpost I'll write about the some of the technical considerations of building LoanPlannerPro.com. In future posts I'll discuss more technical challenges, internationalisation (i18n), deployment, hosting, design, revenue, promotion and much more.

The Problem with Existing Solutions

Traditional mortgage calculators fall short in several key areas:

  • Single mortgage assumption
    Most calculators only handle one mortgage at a time.

  • Oversimplified interest rates
    They don't account for different risk classes based on Loan-to-Value (LTV) ratios.

  • No fixed period modeling
    They can't handle scenarios where you have a fixed rate for a certain number of years that then reverts to a variable rate.

  • Poor mobile experience
    Many are desktop-centric with clunky mobile interfaces.

  • Static calculations
    You often need to hit "calculate" buttons instead of seeing real-time updates

Technical Architecture Decisions

Frontend Stack Choice

I chose React.js with Vite for the frontend because Vite provides lightning-fast hot module replacement during development and React's component-based architecture perfectly suits the modular nature of the mortgage parts.

For styling I chose TailwindCSS because it enables rapid prototyping with utility classes and it has a consistent design system and that is easily maintainable. Dark mode support is built-in and trivial to implement. Same goes for the Mobile-first approach I wanted to employ, this aligns perfectly with my responsive design goals. Also, I didn't want to spend a lot of time on writing CSS rules but focus the little time I have on the functionality of the calculator instead.

State Management Philosophy

Rather than reaching for Redux or Zustand, I implemented a functional programming approach using React's built-in hooks with localStorage persistence. Here is some code from the project to see what that looks like:

// State for mortgage parts - load from localStorage if available
const [mortgageParts, setMortgageParts] = useState(() => {
const savedMortgageParts = localStorage.getItem('mortgageParts');
return savedMortgageParts ? JSON.parse(savedMortgageParts) :[DEFAULT_MORTGAGE_PART];
});


// Save mortgage parts to localStorage whenever they change
useEffect(() => {
localStorage.setItem('mortgageParts', JSON.stringify(mortgageParts));
}, [mortgageParts]);

This approach ensures Predictable state updates by using pure functions. Pure functions also make debugging a lot easier. Data persistence by using LocalStorage, this way the user inputs survive browser refreshes and sessions. Real-time reactivity, useEffect hooks trigger recalculations on any input change. Testability is also improved this way because pure calculation functions are easy to unit test. The solution is Client-side only, keeps things simple. No server is required, this way I can keep hosting costs to a minimum.

Real-time Calculation Engine

The core challenge was building a calculation engine that handles complex mortgage structures while remaining performant. Each mortgage part can have:

  • Individual interest rates with multiple risk classes

  • Different mortgage types (annuity, linear, interest-only)

  • Fixed-rate periods that transition to variable rates

  • Additional payments with custom timing and duration

  • Overlapping time periods across multiple parts

The solution uses a month-by-month calculation approach, here is more code from the app:

// Calculate mortgage payments
const calculateMortgage = useCallback(() => {
const results = calculateAmortizationSchedule(mortgageParts, propertyValue);
setCalculationResults(results);
}, [mortgageParts, propertyValue]);

// Calculate whenever mortgageParts change
useEffect(() => {
calculateMortgage();
}, [mortgageParts, calculateMortgage]);

Conclusion

Thank you for reading my post! The mortgage calculator is currently in active development, please have a look at it while I'm developing. Looking forward to seeing your feedback.

posted toAvatar for product Loan Planner Pro
Loan Planner Pro