Every loan app shows an EMI (equated monthly installment). The formula looks intimidating, but it's simple once you see where it comes from. Here's the math, an implementation, and a month-by-month breakdown.
The formula
EMI = P × r × (1 + r)^n / ((1 + r)^n − 1) - P = principal (loan amount)
- r = monthly interest rate (annual rate ÷ 12 ÷ 100)
- n = number of monthly payments
The result is a fixed payment where the balance reaches exactly zero after n payments.
Implementation
function calculateEmi(principal, annualRatePercent, years) { const n = years * 12; const r = annualRatePercent / 12 / 100; // Edge case: 0% interest would divide by zero in the formula if (r === 0) return principal / n; const factor = Math.pow(1 + r, n); return (principal * r * factor) / (factor - 1); } console.log(calculateEmi(1_000_000, 9, 20).toFixed(2)); // ≈ 8997.9 per month On ₹10,00,000 at 9% for 20 years, you pay about ₹21.6 lakh in total, so more than half of that is interest.
Where the money actually goes: amortization
Each month, interest is charged on the remaining balance, and whatever is left of the EMI reduces the principal.
function amortize(principal, annualRatePercent, years) { const r = annualRatePercent / 12 / 100; const n = years * 12; const emi = calculateEmi(principal, annualRatePercent, years); let balance = principal; const rows = []; for (let month = 1; month <= n; month++) { const interest = balance * r; const principalPaid = emi - interest; balance -= principalPaid; rows.push({ month, interest, principalPaid, balance: Math.max(balance, 0) }); } return rows; } In the first month of the example above, about ₹7,500 goes to interest and only about ₹1,500 reduces the loan. This is why early prepayments save so much: they cut the balance that interest is calculated on.
Edge cases to handle
- Zero rate: guard against division by zero, as above.
- Floating-point drift: the final balance may be a tiny non-zero number. Clamp it, and round only for display.
- Invalid input: negative or empty values should return an error, not
NaN. - Real lenders differ slightly: rounding rules, processing fees, and daily vs. monthly compounding can change the figure by a few rupees.
Try it without writing code
If you just want the numbers, there's a free EMI calculator and a loan comparison calculator on Erapse, a site I run. They're handy for sanity-checking your own implementation against.
What would you add to a loan calculator? Prepayment simulation? Floating-rate changes?