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)