DEV Community

Hugo Rus
Hugo Rus

Posted on

How to Build an AI-Powered Personal Finance App with React Native and Expo

  • Four Postgres tables + RLS cover 90% of a personal finance MVP
  • Rules-based categorization first, LLM fallback second (the LLM's job is bootstrapping the rules)
  • Skip Plaid at v1: manual entry, done well, is a real product
  • Prompt-scaffold the v1, spend your time on categorization heuristics and first-run UX

Personal finance is one of those categories where the market keeps growing but the incumbents keep frustrating users. Mint shut down, YNAB raised prices, and Rocket Money spent its way to a huge user base. If you're a React Native dev thinking about building in this space, 2026 is a great time. AI-native tooling collapses the scaffolding phase enough that a solo dev can ship a real v1 in a week.

Here's how I'd approach it end to end.

The core data model (Postgres via Supabase)

Four tables cover 90% of what a personal finance app does:

create table accounts (
  id uuid primary key default gen_random_uuid(),
  user_id uuid references auth.users not null,
  name text not null,
  type text check (type in ('checking','credit','cash','savings')),
  currency text default 'USD',
  balance numeric(14,2) default 0,
  created_at timestamptz default now()
);

create table categories (
  id uuid primary key default gen_random_uuid(),
  user_id uuid references auth.users not null,
  name text not null,
  icon text,
  color text,
  monthly_budget numeric(14,2)
);

create table transactions (
  id uuid primary key default gen_random_uuid(),
  user_id uuid references auth.users not null,
  account_id uuid references accounts not null,
  category_id uuid references categories,
  amount numeric(14,2) not null,
  merchant text,
  notes text,
  occurred_at timestamptz not null,
  created_at timestamptz default now()
);

create index on transactions (user_id, occurred_at desc);
Enter fullscreen mode Exit fullscreen mode

Enable RLS on every table with user_id = auth.uid() policies. This is not optional in a finance app. It's the difference between "shipped an MVP" and "leaked a stranger's bank data."

The screen tree

Expo Router, tabs at the root:

  • (tabs)/index.tsx: home with month spend, budget remaining, category donut, recent transactions
  • (tabs)/transactions.tsx: list, grouped by day, with search + filter
  • (tabs)/budgets.tsx: card per category
  • (tabs)/insights.tsx: charts (I use victory-native for these)
  • (tabs)/settings.tsx: biometric toggle, currency, CSV export, dark mode
  • add-transaction.tsx: big number pad, merchant autocomplete, category picker

Add-transaction is the one screen users touch daily. Optimize the hell out of it.

The AI categorization loop

Two layers:

  1. Rules table. Regex on merchant string -> category_id. Covers 70–80% of what you see in practice ("STARBUCKS.*" -> Coffee).
  2. LLM fallback. For unmatched merchants, prompt a model with the merchant + the user's category list, ask for { category_id, confidence }. Store the answer so it becomes a rule. Cache aggressively: the same 100 merchants generate 80% of a user's transactions.

Do the rules first, add the LLM later. It's the correct order because the LLM's whole job is to bootstrap the rules table.

Bank connections: later, not now

Every finance-app tutorial jumps straight to Plaid. Don't. Plaid charges per connected user per month once you're out of the free tier, and it comes with a real support burden ("why does my bank keep disconnecting?"). Ship a well-designed manual tracker first. Add Plaid in v2 as a Pro feature once you have signal that users actually want the automation.

If and when you do connect, use their Link SDK. Never accept bank credentials in your own UI, ever.

The AI-native way to scaffold all of this

I've built React Native apps by hand and by prompting, and there's no serious argument for hand-scaffolding a v1 anymore. Prompt the whole thing:

A personal finance app with tabs: home, transactions, budgets, insights, settings. Home shows monthly spend, remaining budget, category donut chart. Add-transaction has a big number pad, merchant autocomplete, category picker, account selector. Use Supabase for auth + data. Enable RLS. Dark palette, subtle green for income, subtle red for expenses.

Something like RapidNative will spit out a real Expo project: real navigation, real Supabase client, generated types matched to the schema. You spend your time on the actually-hard parts (categorization heuristics, chart clarity, first-run UX) instead of typing useNavigation for the eightieth time in your life.

Whatever tool you pick, verify it exports plain code. You want to own the project, not rent it.

Security checklist before you ship

  • Biometric unlock (Expo LocalAuthentication), required on cold start after N minutes.
  • No sensitive fields in Sentry / analytics payloads.
  • RLS on every table.
  • HTTPS only (default in Expo, but audit anyway).
  • Data export + delete-my-account (GDPR/CCPA, also good UX).

What I'd skip on day one

  • Investment tracking (whole different data shape).
  • Bill negotiation / subscription cancellation (Rocket Money moat; expensive to build).
  • Real bank connections (Plaid).
  • Household / joint budgeting (v2 feature).

Ship view-only + manual + smart categorization. That's a real product.

Try the prompt path first

Even if you're a seasoned dev, prompt the first version before you write a line. Worst case you throw it out. Best case you shave weeks off your MVP. The free tier is enough to see whether the output is close to what you'd build.

Ship soon. The category is wide open. If you're building in fintech-adjacent RN right now, drop a comment with what you're working on. Curious what the categorization edge cases look like in other people's data.

Top comments (0)