DEV Community

cattail
cattail

Posted on

How I built a desktop budgeting app with Flask, SQLite, and Chart.js

I'm a finance student, not a CS major. Last year, I realized I was paying $180 annually to a budgeting app. So I decided to build my own. Here's how it went.

Why a Desktop App?

I wanted three things:

  • No cloud. My financial data stays on my machine.
  • No subscription. Pay once, use forever.
  • No setup. Double-click and it works.

A local web app (Flask + browser) checked all three boxes.

The Stack

Layer Technology
Backend Python + Flask
Database SQLite
Frontend HTML, CSS, vanilla JavaScript
Charts Chart.js
Packaging PyInstaller

I chose Flask because it's lightweight. SQLite because it's zero-config. Chart.js because it looks great out of the box.

What the App Does

  • Monthly budget with auto-generated bar and pie charts
  • Daily transaction tracking with keyword-based category matching
  • Multi-currency support with real-time exchange rate preview
  • Savings goals with progress bars and milestone celebrations
  • Subscription manager with billing countdowns
  • Debt payoff comparison (Snowball vs Avalanche)
  • Asset and liability tracking for net worth overview
  • Full bilingual support (English and Chinese)

The Architecture

The app runs a local Flask server. On startup, it opens the user's browser automatically. All data lives in a single database.db file next to the executable.

Here's a simplified view of the project structure:

budget_tracker/
├── app.py
├── models.py
├── routes.py
├── templates/
│ ├── base.html
│ ├── index.html (dashboard)
│ ├── budget.html
│ ├── transactions.html
│ ├── annual.html
│ ├── savings.html
│ ├── subscriptions.html
│ ├── debt.html
│ ├── assets.html
│ └── settings.html
├── static/
│ ├── css/style.css
│ └── js/
│ ├── charts.js
│ └── app.js
└── database.db

Key Design Decisions

1. Keyword Auto-Categorization

Users can set rules in Settings. Type "Starbucks" in the note field, and the category auto-fills to "Food." This is done with a simple dictionary lookup, no AI required.

2. Multi-Currency Handling

The Settings page stores exchange rates. When a user logs a transaction in EUR, the app converts it to their base currency (e.g., USD) in real time. The converted value is stored in a separate base_amount column.

3. Proactive Alerts

The dashboard auto-refreshes every 30 seconds via AJAX. If a budget category exceeds 80%, the card turns red. If a subscription bill is due within 7 days, it shows a countdown. No user action needed.

Packaging with PyInstaller

The final step was turning the Python project into a single .exe file:

pyinstaller --onefile --add-data "templates;templates" --add-data "static;static" app.py

The output is about 21 MB. Users download, unzip, double-click, and their browser opens automatically. No Python, no pip, no terminal.

What I Learned

  • Start simple. My first version was just a budget table and a transaction log. I added features one by one based on my own needs.
  • SQLite is enough. For a local single-user app, you don't need PostgreSQL.
  • Chart.js is wonderful. Responsive, customizable, and the CDN link is all you need.
  • Ship before you feel ready. I wanted to add bank sync and a mobile app. Instead, I launched with what I had. Glad I did.

Try It

Fortune Desk is available on itch.io for a one-time purchase. No subscription, no cloud, no accounts.

If you're a developer thinking about building your own tool — do it. The skills you gain are worth more than any app you'll replace.

Top comments (0)