Budget Calculator
Live· alphaCost-of-living calculator covering 10 countries across Asia and the Middle East. Five lifestyle tiers from lean to comfortable, with per-city breakdowns for housing, food, transport, healthcare, government costs, and visa fees. Data sourced from primary research and auto-generated via a YAML pipeline.
AI-generated: this write-up was drafted by AI from the project's source code and may contain inaccuracies.
Budget Calculator is a cost-of-living estimator for 10 countries across Asia and the Middle East (JP, TH, ID, VN, MY, KR, TW, PH, LK, AE), each with multiple cities and five lifestyle tiers from lean to comfortable+++. It breaks a monthly budget into housing, food, utilities, communications, transport, government costs, and one-time move-in costs, and converts everything into a chosen display currency at live FX rates. The country cost data is not hand-written: it is researched as structured YAML, validated, and compiled into a TypeScript module by a code-gen script.
Architecture
The calculation core is a set of pure functions over plain data — no rendering, no fetching. calculateBudgetTotals takes a BudgetConfig (country, city, tier, per-field overrides) plus a CountryDefinition and returns monthly and annual totals. calculateGovernmentCosts resolves health insurance, income tax, local tax, pension, and mandatory fees by income bracket. calculateMoveInCosts, calculateYear1Costs, and calculateDeltas (the Compare-mode diff) are separate functions over the same data. All stored amounts are in local currency; converting to the display currency is the caller's job, done through a shared FX-rate service.
research/costs/*.yaml (10 countries, primary research)
│
│ npx tsx scripts/generate-budget-data.ts
│ validate() · js-yaml parse · emit TS
▼
lib/budget/countries.ts (AUTO-GENERATED — do not edit)
│
▼
┌──────────────────────────────────────────────┐
│ Pure calculators (lib/budget) │
│ calculateBudgetTotals · calculateGovernment- │
│ Costs · calculateMoveInCosts · calculateYear1 │
│ · calculateDeltas · findAffordableCities │
└──────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ BudgetPlanner (useReducer + useFxRates) │
│ Explore · Compare · Reverse modes │
│ local → display currency · URL-hash share │
└──────────────────────────────────────────────┘Data pipeline
Country data lives in one YAML file per country under research/costs/. scripts/generate-budget-data.ts reads each file with js-yaml, runs a validate() pass, and emits lib/budget/countries.ts with an AUTO-GENERATED — DO NOT EDIT header. Validation is strict: health-insurance brackets must be exactly the six defined income brackets, every city must define all five tiers, and rent must be present for each tier. The script maps snake_case YAML keys to the camelCase TypeScript types and refuses unknown pension systems, so a malformed research file fails the build instead of shipping bad numbers. Editing the runtime module by hand is not part of the workflow — the YAML is the source of truth.
Government costs use pre-computed bracket lookups rather than tax formulas: each country's YAML lists an annual amount per income bracket, and calculateGovernmentCosts looks up the relevant entry. Cities can override country-level rental conventions and health-insurance brackets. Per-field data confidence is tracked — listed prices (rent, utilities, transport) carry the city's confidence, while variable lifestyle costs (groceries, eating out) are dropped one level.
Modes
The UI (BudgetPlanner, useReducer state, persisted to the URL hash for sharing) has three modes:
- Explore — pick a country, city, tier, and income bracket; see the full breakdown with per-field overrides, a cost chart, move-in costs, and country-specific gotchas. Japan adds a "missed costs" section (NHK fee, healthcare copay, consumables) that other countries don't surface.
- Compare — two configurations side by side, with
calculateDeltasreporting absolute and percentage differences per category. - Reverse —
findAffordableCitiesiterates every country/city/tier combination, totals living plus government cost, converts to the display currency, and returns those at or under a target monthly budget, sorted highest tier first.
The budget output deep-links into the Golden Handcuff planner and back, sharing the FX-rate service and tier mappings so a chosen city's cost becomes a scenario input.
Maturity
This build is live and usable, but alpha-stage. The cost numbers come from primary research with per-field confidence labels, not a continuously updated data feed, and each country's data carries an "as of" date and a confidence level shown in the footer. Treat the output as a structured estimate, not an authoritative quote.