← All posts

Cashflow Simulator: Next.js Deep Dive

What Is It?

The Cashflow Simulator is a full-stack financial planning tool built for Thai Baht (฿) markets. It lets users model income streams, expense categories, and investment scenarios in real time — no backend, no database, no auth.

Everything runs in the browser. State lives in React. Calculations are pure functions. The only “server” is Vercel’s edge network serving static assets.

Why Next.js?

For this project, Next.js made sense over Astro because:

  1. Dynamic interactivity — The simulator is a rich client-side app with complex state. Astro’s islands model would have meant hydrating the entire thing anyway.
  2. App Router familiarity — The file-based routing and layout system fit naturally for a multi-view financial tool.
  3. React ecosystem — Access to charting libraries, form validation, and financial math utilities.

Architecture

The core data model is a CashflowScenario object:

interface CashflowScenario {
  income: IncomeStream[];
  expenses: ExpenseCategory[];
  investments: InvestmentEntry[];
  period: 'monthly' | 'quarterly' | 'yearly';
  currency: 'THB' | 'USD';
}

All calculations are pure functions that take a scenario and return derived values — net cashflow, savings rate, projected balance. No side effects, fully testable.

Thai Baht Support

Localizing for Thai Baht meant:

The currency system is pluggable — adding new currencies is a one-line change to the config.

Real-Time Calculations

React’s useMemo does the heavy lifting. Every derived value is memoized based on the scenario state. Updates to any input field trigger only the affected calculations, not a full recompute.

For the chart data, I use a rolling window algorithm that projects 12 months of cashflow given current inputs. The projection updates instantly as the user types — no debouncing needed at these calculation sizes.

Deployment

Vercel’s zero-config deployment made this trivial. Push to main, preview URL appears, merge to deploy to production. The entire CI/CD pipeline is git push.

The one gotcha: Next.js 16’s app router requires Node 18+. Vercel handles this automatically, but local dev needed a version bump.

Lessons Learned

The simulator is open source. View the code on GitHub.