Jaarruimte: van Blueriq naar React in weken
Een pension-calculator voor NN die al jaren in een legacy rules engine draaide. Met Speckit en AI omgezet naar een moderne React-app. Niet in maanden. In weken.
De opdracht
Bij NN draaide een jaarruimte-calculator in Blueriq. Die engine is geschikt voor bedrijfsregels, maar voor een moderne gebruikerservaring en snelle iteratie was het omslachtig geworden. Klein wijzigingetje in de UI? Een heel release-proces.
De vraag: kunnen we die calculator porten naar een standalone React-app, zonder de bedrijfsregels opnieuw te moeten schrijven? En vooral: kan dat snel?
De Speckit-aanpak
Speckit is een spec-driven-development-framework. In plaats van code te schrijven, beschrijf je wat het systeem moet doen in een markdown-spec. Een AI-model genereert daar dan de code uit. Dat klinkt als magic, maar werkt verrassend goed voor afgebakende, regel-gedreven software. Precies wat een jaarruimte-calculator is.
Onze eerste spec zag er zo uit:
# jaarruimte calculator
## doel
Een calculator die de jaarruimte (aftrekbaar bedrag voor pensioenopbouw)
berekent volgens de regels van de Belastingdienst.
## inputs
- bruto_inkomen: currency, required, min 0
- geboortedatum: date, required
- al_ingelegd_voor_pensioen: currency, default 0
## constanten (2026)
- factor: 0.133
- max_aftrekbaar: 35463
- aow_franchise: 17663
## berekening
pensioen_grondslag = max(bruto_inkomen - aow_franchise, 0)
bruto_jaarruimte = pensioen_grondslag * factor
netto_jaarruimte = min(bruto_jaarruimte, max_aftrekbaar) - al_ingelegd_voor_pensioen
## ui
- Form met drie inputs, live berekening
- Resultaat boven de fold
- Tooltip op "?" met uitleg van de formuleSpeckit las deze spec en genereerde een werkende React-component in één pass. Niet perfect, wel werkend. Daarna nog wat handmatige polish op styling en edge cases, en we waren klaar voor review:
import { useMemo, useState } from 'react';
const FACTOR_2026 = 0.133;
const MAX_AFTREK = 35_463;
const AOW_FRANCHISE = 17_663;
export function Jaarruimte() {
const [brutoInkomen, setBrutoInkomen] = useState(0);
const [alIngelegd, setAlIngelegd] = useState(0);
const jaarruimte = useMemo(() => {
const grondslag = Math.max(brutoInkomen - AOW_FRANCHISE, 0);
const bruto = grondslag * FACTOR_2026;
return Math.max(Math.min(bruto, MAX_AFTREK) - alIngelegd, 0);
}, [brutoInkomen, alIngelegd]);
return (
<form>
<label>
bruto inkomen
<input
type="number"
value={brutoInkomen}
onChange={(e) => setBrutoInkomen(Number(e.target.value))}
/>
</label>
<label>
al ingelegd voor pensioen
<input
type="number"
value={alIngelegd}
onChange={(e) => setAlIngelegd(Number(e.target.value))}
/>
</label>
<p className="result">
je jaarruimte: <strong>€{jaarruimte.toFixed(0)}</strong>
</p>
</form>
);
}Resultaat
De calculator werkte op productie-kwaliteit, in een fractie van de tijd die een handmatige port gekost had. Belangrijker: de bedrijfsregels staan nu leesbaar in markdown. Iemand zonder technische achtergrond kan de spec lezen en commentaar geven. De AI genereert de code opnieuw.
Wat we onderweg leerden:
- Spec-first werkt goed voor regel-gedreven domeinen (calculators, validaties, workflows). Minder voor complex UI-werk met veel state.
- AI-generatie is géén vervanging voor engineering-oordeel. Review van elke output blijft nodig, vooral op uitzonderingen en beveiliging.
- Leesbare specs geven het team de controle terug. De bedrijfsregel zit niet meer opgesloten in code.
Legacy-app die vervangen moet worden?
Vaak kan het sneller dan je denkt. Als de bedrijfsregels helder zijn en het probleem goed afgebakend, is Speckit een verrassend krachtig pad.
Brainstorm met ons