DOCS · UPDATED 29 SEPTEMBER 2026

Put a Valnivo widget on your site

Financial calculators, each one line on your page. No account, no key, no bill, and nothing your visitor types reaches us. Every one runs live in the library below, beside the line that embeds it.

Nothing to install or sign up for. Your visitor's figures never leave their browser, and a widget sets no cookie and stores nothing there. Framed from valnivo.eu, the widget is still a request to our host, which sees it as any server does — an IP address and the usual request details, as our privacy notice describes — so your own notice may need to mention it; the standalone package makes no request at all. Parameters are only ever added, never renamed — see what will not break.

§ One line, and you are done

<script src="https://valnivo.eu/valnivo.js"
        data-valnivo="projection" data-currency="EUR" data-locale="fr-LU"></script>

The widget appears where the tag sits. Swap projection for any name in the library and add that widget's parameters as data- attributes. The loader builds the frame and keeps it the height of its contents — 7 kB, no dependencies, and its address never changes.

Or have it written for you: the configurator ticks calculators, sets currency, language and accent, and hands you the finished line.

placed by the loader · projection

Not a screenshot: the loader inserted that frame from the tag above, and it sized itself.

§ Several of them, in one frame

Four separate embeds boot four copies of React: measured here, 1,242 KB of JavaScript against 346 KB for the same four in one frame. So one widget holds the others:

<div data-valnivo="page" data-widgets="projection:6,loan:6,emergency:12"></div>
<script src="https://valnivo.eu/valnivo.js"></script>
NameWhat it doesDefault
widgets Which calculators, in what order, and how wide — name:width, comma separated. The width is in twelfths and may be 4, 6, 8 or 12; anything else, or a name left bare, is full width. Below about 760px they all stack. A name we do not have is ignored rather than guessed at, and a calculator named twice appears once.

A row always fills. Widths decide who sits beside whom — two at 6, or 8 beside 4 — and whatever is left over is shared out, so mortgage:8,rentvsbuy:8 draws as two full-width rows rather than two thirds of one each with the last third empty. fit=0 keeps the older behaviour, where a width was an absolute span and a short row was left short.
projection:12

Every shared parameter applies to the whole page — one currency, one language, one theme, one accent, one licence. Each calculator's code is fetched only if you placed it, so a page of two ships two.

Opening each calculator on your own figures

Prefix any parameter with the calculator's name and a dot, and it reaches that one and no other:

<div data-valnivo="page"
     data-widgets="mortgage:6,rentvsbuy:6,cashvsmortgage:12,projection:12"
     data-mortgage.price="600000"
     data-mortgage.rate="3.2"
     data-rentvsbuy.rent="2200"
     data-projection.save="1500"></div>
<script src="https://valnivo.eu/valnivo.js"></script>

Or, as an address:

https://valnivo.eu/embed/page.html?widgets=mortgage:6,rentvsbuy:6,cashvsmortgage:12,projection:12&mortgage.price=600000&projection.save=1500

A bare name reaches nobody on a composed page, deliberately. years belongs to nine of these calculators, rate to four and amount to three, so ?years=20 would set all of them at once. On a page of a single calculator both forms work. Ranges and defaults are unchanged by a prefix; a prefix naming a calculator you did not place says so once in the console. Currency, language, theme, accent and read-only belong to the page: one frame is one of each.

When not to use it. One frame is one block — you cannot put your own heading between two calculators inside it. For that, give each its own frame.

§ Sending somebody the answer

Every embed carries a Share these figures link in the corner. It hands back the address of the same calculator, or the same arrangement, with the figures the visitor has moved it to:

https://valnivo.eu/embed/mortgage.html?price=620000&rate=3.4&years=25&upkeep=310

Same names as opening on your own figures, so a shared link pastes straight back into a data- attribute.

It is a link before it is a button. A frame may only write to the clipboard if the page holding it allowed that, and most of the iframes in the world holding these widgets were written before this existed — so clicking copies where it can and opens the scenario in a new tab where it cannot. If you frame the widgets by hand rather than with the loader and want the copy to work, add allow="clipboard-write" to your iframe; the loader does it for you. The licence is never in the link, because a link is a thing people forward and a licence is a credential. Nothing about the visitor is in it either: it carries figures they typed, and it is made in their browser — we are not told that it was made, and there is nothing on our side that holds it. A widget posts its height to the page framing it and nothing else, so embedding one never gives a host a way to read what a visitor types.

The configurator works from the other end: tune its preview, and its link, snippet and frames all carry those figures.

§ Ready-made arrangements

The page widget with its calculators already chosen. Each is one address — copy it, open it, or take it into the configurator. Each carries its own Share these figures link.

An arrangement places calculators; it does not join them up. Each still stands on its own figures, and nothing carries a total from one into the next.

They arrange; they do not advise. Each is the same calculators documented below, in one frame, each still carrying the same line inside it: an illustration built on the figures your visitor typed, not a forecast or advice. An arrangement recommends no course, names no product and ranks no option.

Buying a home
What the mortgage costs, whether renting compares, whether paying cash instead compares, and what any of it does to the next thirty years.
mortgage:6,rentvsbuy:6,cashvsmortgage:12,projection:12
Paying off what you owe
How long it takes at the present payment, what the interest costs, and what paying it off frees up.
debt:6,loan:6,projection:12
Retirement
What is held today, what a pot of that size draws down to — and then whether the year it starts in changes the answer, which the three above cannot show because an average has no sequence. No projection sits beside these two: it builds a pot up while they spend one down, so the page refuses that pairing.
networth:6,retirement:6,sequence:12
Moving country
The same pay across a border, how long the cash would last through the move, and the years after it.
crossborder:6,emergency:6,projection:12
Starting something
How many sales cover the fixed costs, what VAT does to a price, and whether an outlay pays for itself.
breakeven:6,vat:6,roi:12
How it all fits together
The three pieces in the order they follow each other: what is held today, what a month does to it, and where that leaves the long run. For a reader who has not met any of it before, rather than one who arrived with a question.
networth:6,flow:6,projection:12

The first of them, running here as one frame, which is exactly what the snippet under it puts on your page:

live · buying a home

Three calculators, one frame, one Valnivo mark — and one copy of React.

<div data-valnivo="page" data-widgets="mortgage:6,rentvsbuy:6,cashvsmortgage:12,projection:12"></div>
<script src="https://valnivo.eu/valnivo.js"></script>

Only the first runs here; the other five are links, and every calculator in them is live further down. Changing one is editing widgets: drop a name, add one from the library, or change a width. None includes the inflation table — it needs countries= to be a sensible size, and a composed page takes no per-calculator parameters, so give it its own frame.

§ Steering the loader

Three data- attributes are the loader's own; every other one is passed to the widget as a query parameter, which is why a parameter added later needs no new loader.

AttributeWhat it doesDefault
data-valnivo Which widget — any name from the library. Required. —
data-height The height to start at, in pixels, before the widget reports its real one. It only decides whether there is a jump on load. 420
data-title The frame's accessible name, read by a screen reader in place of "Valnivo projection". Valnivo <widget>

A container instead of the script tag, to place the widget yourself or to take several from one script:

<div data-valnivo="goal" data-currency="CHF" data-target="80000" data-years="15"></div>
<div data-valnivo="inflation" data-countries="LU,BE,FR" data-height="300"></div>

<script src="https://valnivo.eu/valnivo.js"></script>

Every [data-valnivo] is framed once. Two copies of the same widget size independently — the loader tells frames apart by which one spoke.

If your page renders after the script runs (React, Vue, Angular, htmx), call the loader again; it skips anything already framed:

window.Valnivo.mountAll()          // everything not yet framed
window.Valnivo.mount(element)      // one element you hold a reference to

window.Valnivo also carries origin, version and embedUrl(widget, params) if you want the address without the frame. Loading the script twice is a no-op — the first copy keeps the page.

The loader does three things and no more: it reads your attributes, inserts an iframe and applies a height. No cookie, no storage, no request of its own — the frame carries referrerpolicy="no-referrer", so your page's address never reaches us, and everything that computes lives inside the frame where our CSS cannot touch yours.

§ Or a plain iframe

The loader is a convenience, not a requirement — write the frame yourself if you would rather ship no third-party JavaScript:

<iframe
  src="https://valnivo.eu/embed/projection.html?currency=EUR&locale=fr-LU"
  title="Valnivo projection"
  loading="lazy"
  style="width:100%;border:0;height:420px"
></iframe>

That works on its own; it just cannot resize itself until you listen for its height. Every preview below is a plain iframe like this one.

§ Or install it

Two packages, for the two cases where a script tag is awkward: a build that would rather import a component, and a site whose editor should never meet code.

npm, for React, Vue, Angular and anything else

npm install @valnivo_labs/widgets

See it running — every calculator on that page is rendered by the package, in the page, with a counter showing the requests it makes after load.

Two modes, and the difference matters. standalone puts the calculator itself in your page and makes no request of any kind — no frame, no fetch, no font. If valnivo.eu stopped answering tomorrow, a page built on it would carry on working. Without it, the package builds the same iframe the loader does, which is a kilobyte instead of 54 and takes a correction to a model the day it ships rather than when you update. Pick standalone when the page must not depend on us; pick framed when you would rather not think about updates.

// React
import { ValnivoWidget } from '@valnivo_labs/widgets/react'
<ValnivoWidget widget="projection" params={{ currency: 'EUR', have: 40000 }} />

// Vue 3
import { ValnivoWidget } from '@valnivo_labs/widgets/vue'
<ValnivoWidget widget="loan" :params="{ currency: 'EUR', years: 7 }" />

// Angular — a custom element, so no compiler is involved and an AOT build is fine.
// import '@valnivo_labs/widgets/angular' once, then CUSTOM_ELEMENTS_SCHEMA in the component.
<valnivo-widget widget="mortgage" [params]="figures"></valnivo-widget>

// Anything else
import { mount } from '@valnivo_labs/widgets'
const handle = mount(el, { widget: 'projection', params: { currency: 'EUR' } })
handle.update({ have: 50000 })   // re-points the frame; the height follows
handle.destroy()
// Standalone: the calculator itself, no network at all.
import { render } from '@valnivo_labs/widgets/standalone'
const handle = render(el, { widget: 'projection', params: { have: 40000 }, currency: 'EUR', lang: 'fr' })

// Or as a prop, in any of the wrappers above:
<ValnivoWidget standalone widget="projection" params={{ have: 40000 }} />
<valnivo-widget standalone widget="mortgage" currency="EUR"></valnivo-widget>

An npm package live — params takes any name from the shared parameters or the calculator's own table, and there is one implementation of every calculation behind both modes, so they cannot disagree about an answer. Standalone renders into a closed shadow root: our styles cannot reach your page, yours cannot reach ours, and the Valnivo mark and each calculator's illustration line sit inside it where nothing on your page can take them out — a white-label licence is still the one way the mark comes off. The bundle is fetched only if you ask for standalone, so a page that frames carries none of it — and its translations travel inside it too, one small chunk per language loaded only when lang asks for it, so a page has one language and the words need no request either.

Where it runs

EnvironmentFramedStandalone
React 17, 18, 19yesReact-DOM 18+ (createRoot)
Vue 3.0 – 3.5yesyes
Angular 2 – 21, as <valnivo-widget> with CUSTOM_ELEMENTS_SCHEMAyesyes
Svelte, Solid, Lit, Astro, plain HTML — the same elementyesyes
Next.js, Nuxt, SvelteKiton the clienton the client
Server renderingBoth render on hydration; neither draws HTML on the server.
Browsersanything with <iframe>shadow DOM: Chrome/Edge 53+, Firefox 63+, Safari 10+
WordPress, Webflow, Squarespace, GhostUse the plugin or the loader; neither needs npm.

React, React-DOM and Vue are optional peer dependencies — install only the one your project already has, and the custom element needs none of them.

WordPress

valnivo-calculators.zip · version 0.2.3 · 7.6 kB · SHA-256 235efa894bfe85aee437ee85b0d8de12ae02422d80b5ca3f5313f8ca356f1bf9. Upload it under Plugins → Add New → Upload Plugin, activate, and a Valnivo calculator block is in the inserter — which calculator, currency, language, locale, theme, accent, height and a figures field, all as sidebar fields. For classic editors and page builders there is a shortcode:

[valnivo widget="mortgage" currency="EUR" lang="fr" locale="fr-LU"]
[valnivo widget="loan" years="7" amount="20000"]

It carries no calculator of its own: the plugin emits the placeholder the loader fills, and loads the loader only on a page that shows one — so nothing new reaches us and there is no second implementation of anything. Served from this site rather than wordpress.org; it is four readable files. Webflow, Squarespace and Ghost need no plugin — each has an embed block that takes the one-line loader as it is. Drupal waits for somebody to ask.

§ Parameters every widget takes

NameWhat it doesDefault
currency Any ISO 4217 code — the currency figures are shown in. It changes the labels, not the arithmetic: nothing is converted except where a widget says so. EUR
locale A BCP 47 tag (fr-LU, de-CH, en-GB…) deciding how numbers are grouped and where the currency symbol sits. An unusable tag falls back rather than failing. en-GB
lang The language of the widget's words: en, fr, de, es, it, pt, nl or pl. Separate from locale, which only formats numbers — so locale=fr-LU alone stays in English, and lang=fr is what changes the words. An unknown value falls back to English. On the loader it is data-lang; in the npm package, lang. en
theme dark, light, or auto to follow your reader's own prefers-color-scheme and keep following it if they change it mid-visit. dark
accent Your own accent, as six hex digits — leave the # off, since everything after a # in a URL is a fragment the browser never sends. Three digits work too. It colours the controls and the interaction states; see fitting your design for what it does not colour, and for when it is refused. Valnivo's violet
readonly Shows the figures and switches every control off — sliders, selects, preset buttons. For a worked example on a page that is not meant to be played with, or for handing somebody a layout to look at without their first slider drag making them think those are the figures. It is a real disabled, so the keyboard cannot reach the controls either and a screen reader announces them as disabled rather than as adjustable. Anything but 0, false, no or off switches it on. The configurator offers it as a mode beside the link. off — every embed is adjustable unless you say otherwise
share A quiet Share these figures link in the frame's own corner, beside the mark. It copies an address that reopens the calculator on the figures now on screen — so a visitor who has moved the sliders can send somebody what they are looking at rather than a blank calculator. Set share=0 to take it off. It is not drawn on a white-label page: a licensed embed shows no Valnivo mark, so it shows no link back to us either. on

Unknown parameters are ignored, and a number outside a widget's range is clamped into it rather than breaking the page. A name added here later cannot break an embed that does not use it.

§ The widget library

Grouped by the question they answer. They share the loader, the parameters, the resize message and the conditions of use, so once one is on your page, adding another means changing one word.

Seeing where money leads

Projection liveprojectionWhat you have today, what you put aside each month, and the total after 10, 20 and 30 years. What if one thing changed? livescenarioTwo futures from one starting point: the one you are on, and the one where a single habit changes. What could this grow into? livecompoundHow much of the result was put in against how much was earned, with charges as a knob of their own. Which assumption matters most? livesensitivityEach of the five things a projection rests on moved alone, a stated amount either way, ranked by how much it moves the answer. What did this grow at? livecagrTwo values and the years between them, as one rate a year. What would it take? livegoalA goal read backwards: the monthly figure that gets there. How long would your savings last? liveemergencyCash on one side, a month’s spending on the other, and how many months the first covers. What paying the minimum really costs livecardminimumA card balance at its minimum against the same balance with a little more paid each month. When does a fee for a lower rate pay for itself? livebuydownA fee paid up front against a rate lower for the whole term, and the month it pays for itself. Where does your month go? liveflowWhat comes in and where it went, drawn as a flow. Money put aside is not spending. What you own, less what you owe livenetworthA photograph, not a projection: nothing grows, nothing is discounted. What could you retire on? liveretirementA pot grown to an age the visitor picks, and what it might pay out a month. Does it matter when you retire? livesequenceWalks what the US stock market really did, once for every year somebody could have started.

SEEING WHERE MONEY LEADS

Projection live

Two sliders — what you have today, what you put aside each month — and the total after 10, 20 and 30 years in both future and today's prices, with the return and inflation assumptions on screen and adjustable.

live · projection

Move the controls — it is the real widget, not a picture.

https://valnivo.eu/embed/projection.html?currency=EUR&locale=fr-LU
NameWhat it doesRangeDefault
haveWhat the first slider opens on — money already put by.0–1 000 00020 000
saveWhat the second slider opens on — put aside each month.0–10 000500
rateThe return assumed each year after fees, as a percent. The visitor can still move it.0–155
inflationThe inflation assumed each year, as a percent, which is what today's-prices column divides by.0–152

Message name: projection. These four set where the sliders start and nothing else: a visitor can move every one of them, which is the point of the widget. Added 13 September 2026 — before that this widget opened on its own figures and no others, so an embed that passes none behaves exactly as it always has.

What if one thing changed? live

Two futures from one starting point: the one you are on, and the one where a single habit changes — put aside more, put aside less, or stop altogether. The difference is stated in both nominal and today's prices, over 10, 20 or 30 years.

live · scenario

Move the controls — it is the real widget, not a picture.

https://valnivo.eu/embed/scenario.html?currency=EUR&locale=fr-LU&have=20000&monthly=500&change=200&years=20
NameWhat it doesRangeDefault
haveStarting pot, in whole units.0–200 00020 000
monthlyWhat goes aside each month to begin with.0–3 000500
changeThe size of the change being tried, per month.0–1 000200
yearsWhich of the three horizons opens selected.10, 20 or 3020
knobWhich what-if it opens on: more, less or stop. Anything else opens on the first.those threemore

Message name: scenario.

What could this grow into? live

A starting sum, an amount each month, and — the reason to show this rather than a plain total — how much of the result was put in against how much was earned. Charges are a knob of their own, because a percent a year is the largest drag on a long horizon that anybody actually controls.

live · compound

Move the controls — it is the real widget, not a picture.

https://valnivo.eu/embed/compound.html?currency=EUR&locale=fr-LU&have=10000&monthly=300&years=20
NameWhat it doesRangeDefault
haveWhat the visitor starts with.0–250 00010 000
monthlyAdded each month.0–3 000300
yearsFor how long.1–4020
rateThe return assumed each year before fees, as a percent. The visitor can still move it.0–156
feeThe yearly charge taken off that return, as a percent.0–50.5
inflationThe inflation assumed each year, as a percent, for the today’s-prices figure.0–152

Message name: compound. Return, charges and inflation are sliders inside the widget, so a reader can see what each one costs; the result is shown in both money of the day and today's prices.

Which assumption matters most? live

A starting sum and a monthly amount grown for some years, and then each of the five things the answer rests on — the return, inflation, the monthly amount, the years and the starting sum — moved alone, a stated amount either way, ranked by how much each moves the result. Every row names what it moved, because the order is a statement about those amounts and a reader who cannot see them is being handed a choice as a finding. Measured in today’s prices, since a nominal ranking puts inflation last with a swing of nothing. It says what the answer depends on — never which assumption is right.

live · sensitivity

Over a long horizon the return usually moves it most — which is the one nobody knows.

https://valnivo.eu/embed/sensitivity.html?currency=EUR&locale=fr-LU&have=20000&monthly=400&years=25&rate=6&inflation=2
NameWhat it doesRangeDefault
haveWhat there is to start with, in whole units.0–250 00020 000
monthlyAdded each month.0–3 000400
yearsHow many years it grows for.4–4025
rateThe return, as a percent a year.0–126
inflationInflation, as a percent a year, used to read the result in today’s prices.0–82

Message name: sensitivity. The moves are fixed and printed on every row: the return ±2 points, inflation ±1 point, the monthly amount ±20%, the years ±3 and the starting sum ±10%. One steady return, no charges and no tax; two assumptions moving together can be worse than either alone, which one-at-a-time does not show and the frame says so.

What did this grow at? live

Two values and the years between them, as one rate a year — the only widget here that looks backwards, and it stops there: there is no button to carry the rate forward, because a past rate extended into the future is a forecast wearing a fact's clothes. Money put in or taken out along the way is part of the change, so this is the growth of a figure rather than a return earned, and it says so on its face.

live · cagr

Move the controls — it is the real widget, not a picture.

https://valnivo.eu/embed/cagr.html?currency=EUR&locale=fr-LU&start=10000&end=18000&years=8
NameWhat it doesRangeDefault
startWhat it was worth at the start, in whole units.0–500 00010 000
endWhat it is worth now.0–2 000 00018 000
yearsYears between the two figures.1–508

Message name: cagr.

What would it take? live

A goal read backwards: an amount, a number of years, what you have towards it, and the monthly figure that gets there — plus how much of the total is what you put in and how much is growth. It says "nothing" when the pot already grows past the target on its own, which is the honest answer.

live · goal

Move the controls — it is the real widget, not a picture.

https://valnivo.eu/embed/goal.html?currency=EUR&locale=fr-LU&target=50000&have=5000&years=10
NameWhat it doesRangeDefault
targetThe figure being aimed at, in whole units.1 000–500 00050 000
haveWhat is already there.0–200 0005 000
yearsHow long there is.1–4010
rateThe return assumed each year, as a percent.0–155

Message name: goal.

How long would your savings last? live

Cash on one side, a month's spending on the other, and how many months the first covers — plus the gap to whatever number of months the reader picks. No growth is assumed: this is money that has to be there on the day it is needed. It sets no target — "three to six months" is named as the convention it is, never as a recommendation.

live · emergency

Move the controls — it is the real widget, not a picture.

https://valnivo.eu/embed/emergency.html?currency=EUR&locale=fr-LU&spend=2000&cash=4000&months=3
NameWhat it doesRangeDefault
spendWhat a month costs, in whole units.200–10 0002 000
cashCash that could be reached this week.0–100 0004 000
monthsHow many months the reader wants covered.1–243

Message name: emergency.

What paying the minimum really costs live

A balance, its rate and the card’s own minimum — a percentage with a floor, both read off a statement — against the same balance with a little more paid each month. At an ordinary rate the minimum takes decades and costs more in interest than the balance, which is the figure it exists for. Where the minimum does not cover the interest it says the balance never falls rather than printing a very large number. It ranks nothing: no order to pay debts in, no consolidation, no rate called high or low.

live · cardminimum

Move the controls — it is the real widget, not a picture.

https://valnivo.eu/embed/cardminimum.html?currency=EUR&locale=fr-LU&balance=2000&rate=19.9&percent=2&floor=25&extra=50
NameWhat it doesRangeDefault
balanceWhat is owed, in whole units.100–20 0002 000
rateThe rate the card charges, per cent a year.0–4019.9
percentThe card’s minimum, per cent of the balance.0.5–102
floorThe smallest minimum it will take.0–10025
extraPaid on top of the minimum each month.0–50050

Message name: cardminimum.

When does a fee for a lower rate pay for itself? live

A fee paid up front against a rate lower for the whole term — points in the United States, an arrangement fee most other places. It answers the month it pays for itself rather than giving a verdict, because whether that is worth it turns on how long the loan is kept, which is the reader's fact. Where both rates give the same payment it says the fee does not repay. It names no lender, quotes no rate, and calls none good or bad.

live · buydown

Move the controls — it is the real widget, not a picture.

https://valnivo.eu/embed/buydown.html?currency=EUR&locale=fr-LU&amount=250000&years=25&rate=3.9&lower=3.5&fee=2500
NameWhat it doesRangeDefault
amountWhat is borrowed, in whole units.10 000–1 000 000250 000
yearsThe term.1–4025
rateThe rate without the fee, per cent a year.0–153.9
lowerThe rate the fee buys.0–153.5
feeWhat the lower rate costs up front.0–20 0002 500

Message name: buydown.

Where does your month go? live

What comes in on one side and where it went on the other, drawn as a flow so the shape of a month is visible at a glance. The distinction it insists on: money put aside is not spending — a standing order to savings is drawn apart from the groceries, because it is still the reader's money. It always balances; outgoings above income appear as a source, "from what you already had", rather than as a negative bar.

It reads no file and asks for no statement. The figures are typed on the widget's own controls. A box on a page inviting somebody to drop a bank statement into it is a pattern we will not put on other people's sites, however honest the code behind it — see what it does with your visitor's data. The version inside Valnivo draws the same diagram from a ledger the person already keeps.

live · flow

Move the controls — it is the real widget, not a picture.

https://valnivo.eu/embed/flow.html?currency=EUR&locale=fr-LU&income=3200&home=1100&food=480&transport=220&other=360&aside=300
NameWhat it doesRangeDefault
incomeWhat comes in over the month, in whole units.0–20 0003 200
homeRent, a mortgage payment, and what comes with the roof.0–10 0001 100
foodFood and everyday spending.0–10 000480
transportGetting around.0–10 000220
otherEverything else.0–10 000360
asideMoney moved to savings or an investment — not counted as spending.0–10 000300

Message name: flow. The categories are fixed: a host-defined list would be a form to maintain for every host, and a visitor who has to name six categories before seeing anything is a visitor who has already left.

What you own, less what you owe live

Cash, investments and property on one side, everything owed on the other, with the part reachable without selling a home shown separately. It is a photograph, not a projection: nothing grows, nothing is discounted, no year is named. The borrowed share is stated because it is arithmetic; no level of it is called healthy, high or safe, because that would be a judgement about a person rather than a sum.

live · networth

Move the controls — it is the real widget, not a picture.

https://valnivo.eu/embed/networth.html?currency=EUR&locale=fr-LU&cash=15000&investments=40000&property=250000&owed=180000
NameWhat it doesRangeDefault
cashMoney in accounts, in whole units.0–200 00015 000
investmentsInvestments and pensions.0–1 000 00040 000
propertyProperty, at what it would fetch. Selling costs and tax are not counted.0–2 000 000250 000
owedEverything owed, mortgage included.0–1 500 000180 000

Message name: networth.

What could you retire on? live

A pot grown to an age the visitor picks, and what it might pay out a month at a withdrawal rate they also pick. The rate is deliberately theirs: no figure here is presented as a safe one to live on.

live · retirement

Move the controls — it is the real widget, not a picture.

https://valnivo.eu/embed/retirement.html?currency=EUR&locale=fr-LU&age=40&retireAt=65&have=60000&monthly=500
NameWhat it doesRangeDefault
ageThe visitor's age now.18–7540
retireAtThe age they stop. Never accepted below age.40–8565
haveSaved towards it already.0–1 000 00060 000
monthlyPut aside each month.0–3 000500
rateThe return assumed each year while saving, as a percent.0–155
inflationThe inflation assumed each year, as a percent.0–152
withdrawalThe share of the pot drawn each year once it is being spent, as a percent. No level of it is called safe — it is the visitor’s to set.1–104

Message name: retirement. An age is typed into the frame and goes nowhere — it is not stored, not sent and not part of any record, which is what lets a widget ask for one at all. No state or occupational pension is counted, and nothing is taxed.

Does it matter when you retire? live

A pot nobody draws on cares only about the average: the same returns in any order finish in the same place. Start taking money out and the order becomes the story — a bad first decade sells units at the bottom that are then not there for the recovery, and no run of good years afterwards puts them back. An ordinary retirement calculator cannot show this.

So this one does not use an average. It walks what the US stock market really did, once for every year somebody could have started, and reports how many of those starts the money outlasted. On the defaults, retiring in 1966 and retiring in 1982 are the same pot, the same withdrawal and the same market — and only one of them still has money.

live · sequence

Move the controls — it is the real widget, not a picture.

https://valnivo.eu/embed/sequence.html?currency=EUR&locale=fr-LU&pot=500000&withdraw=20000&years=30
NameWhat it doesRangeDefault
potWhat there is at the start.50 000–3 000 000500 000
withdrawTaken each year, held constant in today’s money — which is what makes inflation-adjusted returns the right series to walk.0–200 00020 000
yearsHow long it has to last. Longer than the record can answer for and it says so rather than guessing.5–5030
stocksShare of the pot in the market, as a percent. The rest earns steady.0–100100
steadyWhat the part not in the market earns each year after inflation, as a percent. Negative is allowed, because cash has spent most of this century losing to it.−2–40

Message name: sequence. Real total returns — dividends reinvested, inflation removed — for the US stock market from 1871 to 2022, derived from Robert Shiller’s public dataset, January to January. One country, one asset class, and the past: the United States has the longest clean record and is also the market that won that century, so a European or Japanese pot did not do this — the frame says so where a visitor reads it. The pot is rebalanced once a year and the withdrawal comes out before the year’s return, which is the convention every published study uses and the conservative one. No tax, fee or state pension is modelled, nothing here forecasts any market, and no rate of withdrawal is called safe — that figure is the visitor’s to set.

ACROSS BORDERS

Pay across a border live

A monthly salary in one country, in another country's money, and what each country's own inflation does to it over time. Thirty-seven countries, from Valnivo's bundled reference table.

live · crossborder

Move the controls — it is the real widget, not a picture.

https://valnivo.eu/embed/crossborder.html?locale=fr-LU&from=LU&to=PT&amount=4000&years=10
NameWhat it doesRangeDefault
fromWhere the salary is paid — ISO 3166-1 alpha-2.Any curated countryLU
toWhere it is being lived on.Any curated countryPT
amountMonthly pay, in the origin country's currency.500–20 0004 000
yearsHow far ahead to show the inflation effect.1–3010

Message name: crossborder. currency is ignored here — each side is shown in its own money.

What this one is not. It does not compare the cost of living, and it says so on screen. Rent, tax, childcare and groceries differ between two countries far more than the conversion does, and Valnivo holds no price-level or purchasing-power data to put a number on that. Please do not present it as a "should I move?" calculator.

Inflation by country live

The inflation figures Valnivo actually projects with — the current rate and the long-run rate it glides to — for all thirty-seven curated countries, searchable, with what they do to a fixed sum over time.

live · inflation

Six countries here, so the preview stays short; leave countries off and you get all thirty-seven. Try the search.

https://valnivo.eu/embed/inflation.html?currency=EUR&locale=fr-LU&countries=LU,BE,FR,DE&sum=1000&years=10
NameWhat it doesRangeDefault
countriesA comma-separated list of alpha-2 codes, in your order. Omit it for all of them.Any curated codesall
sumThe sum whose purchasing power is shown.1–1 000 0001 000
yearsOver how many years.1–3010

Message name: inflation. The figures are the bundled reference table with its date shown; a widget never fetches a live figure, so a table on your page cannot change under you. All thirty-seven rows come to roughly 2 000px, so pass countries= unless you want the full list.

BORROWING

What would this loan cost? live

The monthly payment, the interest over the life of the loan, where each year's payments go — and what paying a little extra each month would change, which is the part a bank's own calculator rarely shows.

live · loan

Move the extra-payment slider — the years and the interest saved follow.

https://valnivo.eu/embed/loan.html?currency=EUR&locale=fr-LU&amount=25000&rate=4.5&years=7&extra=100
NameWhat it doesRangeDefault
amountHow much is borrowed.1 000–500 00025 000
rateThe annual interest rate, as a percent. Decimals are kept, so 4.5 means 4.5%.0–254.5
yearsThe term.1–357
extraThe overpayment the comparison opens on.0–1 000100

Message name: loan. The rate is treated the way lenders quote it — nominal, divided by twelve — so the payment matches a published amortisation table to the cent. It assumes a fixed rate, no arrangement fee, no insurance and no early-repayment charge, and says so inside the frame.

What would this home cost a month? live

The same arithmetic against a price and a deposit, with upkeep, property tax and insurance added, since those are what turn a payment people can quote into a cost they had not planned for.

live · mortgage

Move the controls — it is the real widget, not a picture.

https://valnivo.eu/embed/mortgage.html?currency=EUR&locale=fr-LU&price=500000&deposit=100000&rate=3.5&years=25
NameWhat it doesRangeDefault
pricePrice of the home.50 000–2 000 000500 000
depositWhat is put down. Capped at the price.0–1 000 000100 000
rateThe annual rate, as a percent.0–123.5
yearsThe term.5–3525
upkeepUpkeep, tax and insurance a month — the costs that come with owning and are not the loan.0–5 000250

There is deliberately no affordability widget, and there will not be one without a lawyer's opinion. "How much home can I afford" states what somebody may borrow from their income and debts — a creditworthiness judgement, which is the lender's own regulated duty and close to advice on a regulated mortgage contract. This widget answers what a home would cost, never what you may have.

When would this be paid off? live

Months to clear a balance, the interest along the way, and what paying more each month changes. It also answers the case a calculator usually fudges: when the payment does not cover the interest, it says the debt never clears rather than printing a very large number of months.

live · debt

Drag the payment below the interest — the answer changes in kind, not in degree.

https://valnivo.eu/embed/debt.html?currency=EUR&locale=fr-LU&balance=15000&rate=18&monthly=400&extra=100
NameWhat it doesRangeDefault
balanceWhat is owed.100–100 00015 000
rateThe annual rate, as a percent.0–4018
monthlyPaid each month.0–3 000400
extraThe overpayment the comparison opens on.0–1 000100

Message name: debt. It will never rank several debts, propose an order to clear them in, or suggest consolidating: debt counselling is a licensed activity in Luxembourg and most of its neighbours, and that is the step from arithmetic into advice. The widget points at approved services instead.

DECIDING BETWEEN TWO COURSES

Rent or buy? live

The comparison Valnivo ought to own, because it is a scenario rather than a calculation. Both sides start with the same cash — the deposit plus the costs of buying — and whoever pays less each month invests the difference. Without that last rule the answer flatters whichever side happens to cost more, which is how this sum is usually rigged.

live · rentvsbuy

The last two sliders decide the answer, and nobody knows either of them.

https://valnivo.eu/embed/rentvsbuy.html?currency=EUR&locale=fr-LU&price=500000&deposit=100000&rent=1500&years=10
NameWhat it doesRangeDefault
pricePrice of the home.50 000–2 000 000500 000
depositWhat could be put down.0–1 000 000100 000
rentRent a month instead.200–6 0001 500
yearsCompared over how long.1–3010
mortgagerateThe mortgage rate, as a percent a year.0–123.5
appreciationWhat the home is assumed to gain each year, as a percent. Negative is allowed, because homes do fall.−5–122
growthWhat the renter’s invested difference is assumed to return each year, as a percent.0–155

Message name: rentvsbuy. Buying assumes a 25-year mortgage at a fixed rate, 7% of the price in costs to buy, 1% of the price a year in upkeep and tax, and that the home is not sold. Renting assumes rent rises 2% a year. Neither side is taxed, and deductible mortgage interest — real in Luxembourg — is not modelled. All of that is stated inside the frame too.

Pay cash or take a mortgage? live

Buying outright with cash the reader already has, against borrowing and keeping that cash invested. Both paths start with the same cash and spend the same each month: whatever the borrower pays the lender, the cash buyer invests instead. The home is the same in both and is left out of both figures, so what is compared is investments less what is still owed. It says which path ends higher under the figures set — never which to take — and names no lender and no investment.

live · cashvsmortgage

The return against the mortgage rate decides most of it, and nobody knows the return.

https://valnivo.eu/embed/cashvsmortgage.html?currency=EUR&locale=fr-LU&price=400000&cash=450000&deposit=20&rate=3.5&years=25&growth=5
NameWhat it doesRangeDefault
pricePrice of the home, in whole units.50 000–2 000 000400 000
cashThe cash there is to start with, in both paths. Below the price there is nothing to compare, and the frame says so.0–3 000 000450 000
depositWhat is put down if borrowing, as a percent of the price.0–10020
rateThe mortgage rate, as a percent a year.0–123.5
yearsThe mortgage term.5–3525
growthWhat invested cash is assumed to return each year before charges, as a percent.0–125
feeThe ongoing charge on the investments, as a percent a year.0–2.50.3
inflationUsed only to restate the difference in today’s prices, as a percent a year.0–82
horizonHow many years the two paths are compared over; shorter than the term counts what is still owed.1–4025

Message name: cashvsmortgage. One steady return every year, a fixed mortgage rate, and no tax on either side — relief on mortgage interest and tax on returns differ by country. Buying costs, lender fees and insurance are not included, and the frame says that invested cash can be reached while a paid-off home cannot, which no figure carries. All of that is stated inside the frame too.

FOR A BUSINESS

Would this pay for itself? live

A firm's own costs against its own estimate of time saved, and the month it breaks even. Not consumer finance at all, which makes it the one widget that fits a B2B page where a projection would not.

live · roi

Move the controls — it is the real widget, not a picture.

https://valnivo.eu/embed/roi.html?currency=EUR&locale=en-GB&nowCost=500&newCost=300&setup=1500&hours=10&hourly=40
NameWhat it doesRangeDefault
nowCostWhat is spent today, a month.0–20 000500
newCostWhat the change would cost, a month.0–20 000300
setupOne-off cost of switching.0–100 0001 500
hoursHours a month saved.0–20010
hourlyWhat an hour is worth.0–50040

Message name: roi. When the change costs more than it saves, break-even reads never rather than a negative number of months. Nothing is discounted and nothing is taxed.

How many do you have to sell? live

Fixed costs against what a sale leaves behind, and the number of sales where the two meet — with a profit target on top if you want one. The case it exists for is the one with no answer: where the price does not cover what a unit costs to make, no quantity gets there, so it says so in words and names the figure that caused it. It assumes every sale is the same and that costs split cleanly into fixed and per-unit, and says so in the frame.

live · breakeven

Move the controls — it is the real widget, not a picture.

https://valnivo.eu/embed/breakeven.html?currency=EUR&locale=fr-LU&fixed=12000&price=25&unit=10
NameWhat it doesRangeDefault
fixedCosts a month that do not move with sales, in whole units.0–200 00012 000
priceWhat one is sold for.0–5 00025
unitWhat one costs to make or deliver.0–5 00010
profitProfit wanted a month on top of covering the fixed costs.0–100 0000

Message name: breakeven.

VAT, both ways live

Add VAT to a net price or take it back out of a gross one, with the standard rates of Luxembourg, Germany, France and Belgium as presets. The smallest widget here and the one an ecommerce or accounting page is most likely to want.

live · vat

Move the controls — it is the real widget, not a picture.

https://valnivo.eu/embed/vat.html?currency=EUR&locale=fr-LU&amount=1000&rate=17&mode=add
NameWhat it doesRangeDefault
amountThe price to start from.0–100 0001 000
rateThe rate, as a percent. Decimals are kept.0–3017
modeadd treats the amount as net; remove treats it as gross.add / removeadd

Message name: vat. Taking VAT out divides by 1 + the rate rather than taking the rate off the gross price, which is the usual mistake and always understates the tax. The presets are standard rates as a convenience: which rate applies to a sale is a question about the sale.

§ In Excel, without writing anything

An Office Add-in is a hosted page plus a manifest, so the widgets go into Excel as they are. Install valnivo-excel.xml and a Valnivo button appears on the Home tab, opening a pane beside the sheet.

https://valnivo.eu/valnivo-excel.xml

It reads only the cells you select, only when you ask, and never writes. The manifest declares ReadDocument (it was Restricted until 21 September 2026): select figures in your sheet, press Use the selected cells in the pane, and they become the widget's inputs — nothing is read on load, nothing is watched, and no cell is ever written. The pane makes no request of its own — the same as any embed on this page — and loads Microsoft's Office library only inside Excel itself.

The pane carries three of them, not the whole library, and the reason is on its own face: Excel already has PMT, FV, PV, NPER and RATE, so a loan or a savings pot needs three cells and no add-in. What is in the pane is what a spreadsheet cannot do on its own — the projection as a range, rent against buying, and the dated inflation figures behind both.

Not built: custom functions, the =VALNIVO... kind that put a figure in a cell. A cell holds a number and cannot hold "an illustration built on assumptions, not advice", which is the one thing that travels with every widget here. It is a decision waiting on wording rather than on code — say so if it is what you need, and it moves up the list.

§ Letting a widget size itself

Skip this if you use the loader — it does this for you. Each widget posts its height whenever it changes; apply it and the frame follows:

<iframe id="valnivo" src="https://valnivo.eu/embed/scenario.html?currency=EUR&locale=fr-LU"
        title="Valnivo what-if" loading="lazy" style="width:100%;border:0;height:420px"></iframe>
<script>
  addEventListener('message', function (e) {
    if (e.origin !== 'https://valnivo.eu') return
    if (!e.data || e.data.source !== 'valnivo' || e.data.widget !== 'scenario') return
    document.getElementById('valnivo').style.height = e.data.height + 'px'
  })
</script>

The message is { source: 'valnivo', widget: '<name>', height: <pixels> } and carries nothing else — no figures, no identifiers.

Check e.origin. Any page in any frame can post a message to yours; that line is what stops you resizing on a stranger's word.

Two of the same widget? The message names the widget, not which copy — compare e.source with the frame's contentWindow, which is what the loader does.

A frame with no width gets no message

A widget's height is not a property of the widget. It is a function of the width it is laid out at, and the curve is steep. The same page, measured at four widths:

Laid out atReports
1,076px415px
296px892px
96px1,905px
36px2,696px

So a height measured before your frame has a width is not a smaller truth — it is a different number, several times too large. A frame laid out at zero width sends nothing (display:none, a closed tab, an unopened accordion): yours keeps the height you gave it, and the real one arrives when the frame has a width. Zero is the only width that cannot have been meant, so there is no threshold to trip a genuinely narrow column.

You never have to ask for a fresh measurement. The widget watches its own box and the frame's, so revealing a hidden frame or changing its column produces a new height by itself.

§ Fitting your design

§ What it does with your visitor's data

Nothing at all, and that is a design rule rather than a coincidence. A widget:

  • keeps no account and asks for nothing;
  • writes no cookie and no localStorage, so it needs no consent banner from you on our behalf;
  • makes no request of its own once loaded — the numbers are computed in the browser;
  • runs no analytics and no advertising, ever.

The browser does fetch the widget from valnivo.eu, so our host sees an IP address and the usual request details, as any server would; our privacy notice covers those. If a widget ever stores or sends something about a visitor, this page will say so and there will be an agreement to sign first — it will not change quietly under an existing embed.

§ Showing somebody their own figures

The commonest question here. A widget computes from what your visitor types into it: there is no parameter, token or API that hands a widget somebody's Valnivo data — not an unbuilt feature but the property everything else rests on, since a component that could fetch a person's figures could not be embedded anywhere without an agreement about their data.

Never ask a visitor for a Valnivo recovery code. That code is the master key to a whole ledger — it derives the encryption key for everything, for ever, and cannot be scoped to one view or given an expiry. Our own database rules refuse to serve a ledger to anyone who is not signed in as its owner or a member of its space, so a page collecting one could not use it even if it wanted to.

Which means: a page asking for a Valnivo recovery code is either broken or phishing, and it is not ours. Please do not build one, and tell us if you see one.

What exists instead is the person doing it themselves: in the app they make a share link — one dated snapshot of a projection, with no entries, accounts, categories or name, sealed with a key that exists only inside the link and dead within 48 hours at most. They can revoke it sooner.

https://valnivo.eu/shared/#<id>.<key>

If what you actually need is to show figures for people your organisation manages — clients, members, employees — that is a different product with a different contract: Valnivo Professional, where the organisation is the controller, we are the processor, and a case carries a reference of yours rather than anybody's name. It is in early access: open to firms at no charge, and an account is created by invitation rather than by signing up.

§ The little Valnivo mark

A 17 pixel icon and the word, on a quiet chip in the top corner. It is positioned absolutely and takes no width from the widget, so your own heading never wraps around it. Clicking it opens valnivo.eu in a new tab — it never navigates the frame — and the link carries rel="noreferrer noopener".

On the free tier it does not come off. There is no parameter to hide it, for the same reason the disclaimer travels inside the frame. If it clashes with your design, write to us rather than covering it.

A white-label licence removes it and lets you present the calculation as your own. It is free today — today, and only while Valnivo is running, rather than a right a licence gives you — and issued by hand. What a licence cannot touch is the line inside the frame saying a figure is an illustration and not advice: our name may go; that may not.

§ Conditions of use

A projection is an illustration built on assumptions, and every widget says so inside the frame. Please leave that visible — do not overlay it, clip it out, or place a widget so that the line reads as your own recommendation. Two things follow from the same rule:

§ Changes, and what will not break

§ Still to come

Not built. Tell us which is worth doing first.

§ If something is wrong

Write to support@valnivo.eu with the page you embedded it on and what you saw, or open an issue in the public feedback repository — that one is public, so keep anything private for the email.