29 April 2026
It's all just maths: from Excel to JavaScript
Excel is an extraordinary combination of state, computation, and UI — but for any model used more than once, JavaScript and HTML are a better way to capture the same logic. Here's the same simple property underwrite rendered both ways.
It's all just maths.
I'm a huge fan of Excel — it is an incredible combination of state (memory), computation, and UI.
And it is, of course, deeply embedded in the economy: even the frontier labs like Anthropic and OpenAI are writing AI interfaces that sit on top of Excel models.
However — and especially for models which are going to be used more than once, whether they're standard diligence processes or recurring analyses — JavaScript and HTML are a better way of capturing and managing state, computation, and UI.
The applet below shows the same simple financial model rendered in an Excel-like format and in a JavaScript format.
From Excel to JavaScript
The same property underwrite, two ways. Excel is a sandbox of formulas locked inside cells. JavaScript is the same math — but it composes, scales, and (in the LLM era) writes itself.
Hover any green-outlined cell in the Excel grid to see its formula.
Underwrite as a spreadsheet
| A | B | C | D | E | F | G | H |
|---|
The same model, written as code
Inputs
Cash flows
The actual JavaScript that runs above
function underwrite(inputs) { const { purchasePrice, year1NOI, noiGrowth, exitCap, holdPeriod, ltv, interestRate } = inputs; const loanAmount = purchasePrice * ltv; const equity = purchasePrice - loanAmount; const annualDebtService = loanAmount * interestRate; const cashflows = [-equity]; // Year 0: write the equity check let noi = year1NOI; for (let year = 1; year <= holdPeriod; year++) { let cf = noi - annualDebtService; if (year === holdPeriod) { // Sale at end of hold const exitNOI = noi * (1 + noiGrowth); const salePrice = exitNOI / exitCap; const saleProceeds = salePrice - loanAmount; cf += saleProceeds; } cashflows.push(cf); noi *= (1 + noiGrowth); } return { cashflows, irr: computeIRR(cashflows) }; } // Newton-Raphson — the same algorithm Excel's IRR() uses internally function computeIRR(cf) { let rate = 0.1; for (let i = 0; i < 200; i++) { let npv = 0, dnpv = 0; cf.forEach((c, t) => { npv += c / Math.pow(1 + rate, t); dnpv -= t * c / Math.pow(1 + rate, t + 1); }); const next = rate - npv / dnpv; if (Math.abs(next - rate) < 1e-7) return next; rate = next; } return rate; }
Why move from one to the other?
Excel does
- Math you can see in cells
- Hover-discoverable formulas
- One model per file, one file per deal
- Logic locked inside
.xlsx - Hard to test, hard to diff, hard to share programmatically
JavaScript does the same — and
- Runs anywhere a browser runs
- Loops, conditionals, real data structures
- One function, infinite deals
- Versionable, testable, composable
- An LLM can read the model, explain it, extend it, port it
The JavaScript itself will probably be legible to you even if you don't write JavaScript. I don't think there's a major difference in complexity between the JavaScript functions and the Excel functions. VLOOKUP() or array.map() are both clearly technical.
The JavaScript version is scalable in a way that the Excel version is not. It allows you to separate concerns — verbs, nouns, memory. It can be deployed onto any device without installation. It is one of the biggest ecosystems in the world.
Critically, it is highly legible to the LLM.
For a CTO deciding on tech stack, you're never going to get rid of Excel — but migrating some of the computation from Excel to JavaScript could make sense.