When my wife and I planned for a baby, I tried to figure out her Elterngeld (German parental allowance). Every calculator I found was a black box: enter numbers, get one result, trust us. None of them showed how the number was computed, and several still showed an income limit that was replaced in April 2025.
So I built the opposite — a suite of calculators where every step displays its formula, percentage, and the legal paragraph. This post is about the engineering behind it.
The core idea: tax law as pure functions
German tax law is surprisingly deterministic. § 2c BEEG tells you exactly which deductions to apply, § 32a EStG is literally a piecewise-linear income tax formula. So the whole calculation became a pure TypeScript module:
export function berechneElterngeld(e: Eingabe): Ergebnis {
const { bemessen, monatsSteuer, monatsSV } = bemessungseinkommen(e);
const prozent = prozentSatz(bemessen); // 67% → 65% above €1,200
const basis = Math.min(bemessen * prozent, EG.hoechstbetrag);
return { basis, prozent, schritte: rechenweg(...) };
}
The schritte (steps) array is the product: every intermediate value with its formula and law reference gets rendered on the page. If a number appears in the UI, it exists in the calculation trace.
Tests as a trust contract
Because the target audience will make real financial decisions, every rule got a test:
it('applies 67% up to €1,200 and tapers to 65%', () => {
expect(berechneElterngeld({ ...BASIS, bruttoMonat: 1_000 }).prozent).toBeCloseTo(0.67);
expect(berechneElterngeld({ ...BASIS, bruttoMonat: 2_500 }).prozent).toBeCloseTo(0.65);
});
68 tests now encode the rules: minimum benefit (€300), the cap (€1,800), the April-2025 income limit (€175,000 zvE — one most sites still get wrong), sibling/twin/premature-birth bonuses, and the severance Fünftelregelung (§ 34 EStG). For the Minijob employer-cost model I validated against the official Minijob-Zentrale calculator — to the cent.
The stack
- Astro static output — the whole site ships <200 KB, zero third-party requests
- TypeScript calc modules shared between the page JS and the test suite
- Cloudflare Pages — free hosting, Frankfurt edge for the German audience
- No cookies, no tracking, no signup — calculations run entirely client-side (which also means the privacy policy fits in one paragraph)
What I'd do differently
Translating § 2c BEEG deduction logic into code took three attempts — the interaction between Lohnsteuer, Soli, and Kirchensteuer per month is subtly different from the annual calculation. Testing against the official Prognoserechnung examples caught the drift.
The result is live at rechner.hunterfang.com/en (German/English/Chinese). It launches on Product Hunt next Tuesday — feedback from anyone who knows German tax law would be incredibly welcome, stress-testing the math is exactly what the test suite can't do alone.
Top comments (0)