Skip to content
Stephan.

03Personal

Expense Tracking App

Personal Finance Manager

Flutter expense tracker with local-first storage and cloud sync to PostgreSQL on AWS, usable fully offline.

Company
Personal Project
Role
Solo build — mobile and backend
Category
Full-Stack
012400×1000

/images/work/expense-tracker/cover.webp

Full-bleed project cover. Wide editorial crop of the interface or its subject matter.

01Impact

By the numbers.

2

Platforms, one codebase

Offline

Local-first writes

Sync

Cloud reconciliation

AWS

Hosted PostgreSQL

02Overview

The brief.

Expense tracking happens at the moment of spending — often on patchy mobile data. The app writes locally first and syncs when a connection is available, so recording a expense never depends on the network.

Problem

An expense app that requires connectivity gets abandoned the first time it fails at a checkout. But local-only storage loses everything with the device, and naive sync silently overwrites entries when the same account is used on two phones.

Solution

Local-first architecture: writes land in on-device storage immediately and are reconciled against PostgreSQL on AWS when connectivity returns, with a single Dart codebase covering both platforms.

03Features

What it does.

01

Offline-first entry

Expenses save to local storage instantly; connectivity is never on the critical path.

  • Local storage
  • Flutter
02

Cloud sync

Local records reconciled against hosted PostgreSQL when the device comes back online.

  • AWS PostgreSQL
  • REST
03

Categorisation

Expenses grouped by category to make spending patterns visible.

  • Dart
  • Local storage
04

Spending insights

Aggregated views over categories and time ranges.

  • Flutter
  • Dart
05

Single codebase

One Dart codebase targeting both mobile platforms.

  • Flutter
  • Dart

04Architecture

How it's built.

client

  • Flutter
  • Dart
  • Material design

storage

  • On-device local store
  • Local-first writes

backend

  • PostgreSQL on AWS
  • REST endpoints

sync

  • Reconciliation on reconnect
  • Conflict handling

05Challenges

What was hard.

01

The app has to work with no connection at all

Local store treated as the primary write target, with sync as a background reconciliation rather than a prerequisite.

02

The same account editing from two devices

Reconciliation on reconnect rather than last-write-wins overwriting on push.

06Gallery

A closer look.

021600×1200

/images/work/expense-tracker/01.webp

Interface detail. Crop tight on one screen or one interaction — not a full-page screenshot shrunk down.

031600×1200

/images/work/expense-tracker/02.webp

Interface detail. Crop tight on one screen or one interaction — not a full-page screenshot shrunk down.

041600×1200

/images/work/expense-tracker/03.webp

Interface detail. Crop tight on one screen or one interaction — not a full-page screenshot shrunk down.

051600×1200

/images/work/expense-tracker/04.webp

Interface detail. Crop tight on one screen or one interaction — not a full-page screenshot shrunk down.

07Stack

Built with.

  • Flutter
  • Dart
  • AWS PostgreSQL
  • Local Storage

Outcomes

  • Expense capture that works with no connectivity
  • Single Dart codebase across both mobile platforms
  • Local records reconciled against hosted PostgreSQL