DEV Community

a353551071
a353551071

Posted on

I open-sourced the math behind my dividend calculator

When I built a free dividend payout calculator, the interesting part wasn't the UI — it was the math. Dividend yield, payout ratio, and especially the way a DRIP (dividend reinvestment plan) compounds year over year. So I pulled the formulas out into a tiny, zero-dependency TypeScript library: dividend-math.

This post is the story of the library and the one calculation that surprised me: how reinvestment plus growth quietly outruns a flat high yield.

The library

dividend-math is one file of pure functions. No runtime dependencies, no I/O, fully tree-shakeable. You can npm install dividend-math or just copy src/dividend.ts into your project.

import {
  dividendYield,
  payoutRatio,
  monthlyDividendIncome,
  dripCalculator,
} from 'dividend-math';

// Yield: $2.80 annual dividend on an $80 share
dividendYield({ annualDividendPerShare: 2.8, price: 80 }); // → 3.5 (%)

// Sustainability: dividend vs earnings
payoutRatio({ dividendPerShare: 2, earningsPerShare: 5 }); // → 40 (%)

// Monthly cash flow on a position
monthlyDividendIncome({ investment: 50000, dividendYieldPct: 13 }); // → ~541.67/month
Enter fullscreen mode Exit fullscreen mode

All percentage inputs are plain numbers (5 for 5%); money is in dollars. Returns are numeric and predictable — dividendYield returns NaN for a zero price, payoutRatio returns NaN for zero earnings, so the bad inputs fail loudly instead of producing pretty-looking nonsense.

The interesting one: DRIP compounding

dripCalculator simulates a dividend reinvestment plan year by year. Each year it:

  1. Computes dividends at the current yield on the current share count.
  2. Reinvests those dividends into more shares at the current price.
  3. Adds monthly contributions buying shares at the current price.
  4. Then grows the price by priceGrowthPct and the yield by dividendGrowthPct.
const result = dripCalculator({
  initialInvestment: 10000,
  price: 80,
  dividendYieldPct: 3.5,
  dividendGrowthPct: 10,
  priceGrowthPct: 7,
  monthlyContribution: 100,
  years: 15,
});
// → { shares, finalPrice, finalValue, totalInvested, totalDividends, finalAnnualDividendIncome }
Enter fullscreen mode Exit fullscreen mode

The result that always gets people: a 3.5% yield with 10% annual dividend growth, reinvested, beats a flat 6% yield over a long horizon — because the dividend grows and buys more shares as it does. The starting yield is the wrong number to optimize; the growth rate matters more.

That's the whole reason a "good" dividend yield is usually 3–5%, not 8%+. A high yield often means the price collapsed or the payout is unsustainable — which is why the calculator pairs yield with the payout ratio.

Why pure functions, and why a library at all?

Two reasons. First, testability: every formula is a pure function, so the edge cases (zero price, zero growth, g = 0 in the geometric series for cumulative dividends) are covered by 16 unit tests. Second, reuse: the same dripCalculator drives the DRIP page, the SCHD and QQQI ETF calculators, and the monthly-income page on the live site. One source of truth, no drift.

The live calculator

The library powers dividendpayoutcalculator.com — a free suite with dedicated calculators for SCHD and QQQI, plus yield, payout ratio, growth, and monthly income. No sign-up, runs entirely in the browser.

If you're building anything finance-adjacent and need the math, grab the library. If you just want to run the numbers, the calculator's free.

Thoughts on the DRIP model — anything you'd add to the simulation (tax drag, FX, variable monthly contributions)? I'd love to hear how you'd extend it.

Top comments (0)