Building Yet Another Money App: Bringing the Web To The Desktop
The Goal
I actually had a project in mind — I want to write a better tool for my personal finances. I’m tired of logging into each bank, copying certain data points, plugging them into other programs, such as Excel, and trying to coerce it all to work. I envision a single interface where I can see all of my accounts, easily transfer money between them, manage my expenses, and handle, at least partly, my taxes. Almost everything we do today is geared around money in some way. Everything has a price tag associated with it, and with all those data points, there’s tons of Big Data™ laying around based on my money.
But let’s not get ahead of ourselves — there must be an affordable program that exists for these goals. I’ve used Quicken, GnuCash, YNAB, and a few others. They tend to be fantastic for what they focus on, but all these programs begin and end at viewing my money. They don’t make transfers or account management easier (& for good reason). However, they also end their usefulness on money, instead of letting my go through my money to learn about myself.
When a return cutoff is coming up, I should be notified by my money app, and I should be able to pull up that purchase in my money app to show the receipt if I do need to return it. Super easy, super simple. When I have re-occurring bills for subscriptions that I don’t use, perhaps it should remind me to double check that subscription. Maybe I don’t need five $15 subscriptions for watching online videos.
I have not found an alternative that gets remotely close to this, and good luck trying to do all of this in Excel.
My Experience & Technology
I have multiple years of experience with .NET, nearly almost all of it with either console jobs or ASP.NET MVC sites as a full stack developer. I’ve writen all of it — from the database to the basic HTML form to the enhanced web app experience.
I’ve tried experimenting in Windows Forms and WPF before, and I’ve never been a fan of the XAML. I know I should probably just get over it, but I find the content-first idea of HTML to be more straightforward to scaffold and understand. They very name of HyperText Markup Language. HyperText is text displayed on a computer display with hyperlinks to other text that the reader can immediately access. Yes, that’s what I want. I want to display text, such as a credit card transaction, with a link to it on a statement, on the credit card’s website, and a link to the vendor, with potentially a receipt and warranty information. I want to annotate that HyperText so the user and machine can respond to it. I want to easily offer multiple styles so the format of that markup and text to offer theme support.
So, I want to use HTML and CSS. JS? Probably, if I have to. But there’s a new technology out for a bit, so it’s a little mature —Blazor. What if I use Blazor to write my app? Sure, it’s a web app, but we’ll worry about that later. I just want to get a proof of concept going.
So, I get on my merry way, hook up some Selenium to a basic Blazor UI with a EFCore DbContext and start hashing it out, like a traditional web backend. The server opened up Selenium and scraped my bank for my info, and it worked. Walaa! Woohoo! But now my 2nd bank. I hold my breathe, reconfigure my app to support multiple banks, and other Yipee! One list of scraped accounts from two of my banks.
However, this is when it hits me — how do I secure this? This is just as dangerous as Plaid/YNAB/Mint/Quicken. I’m letting the server take a username/password that can do anything and everything to my bank accounts. Well, shucks. That ain’t good. I don’t like that. I don’t like it with Mint, and I don’t like it with this.
The Predicament
This is when I realized I have one additional requirement: I don’t want some random web app saving my password or learning all my financial data, including one I write. I never liked YNAB, Mint, or Quicken for that reason. Will YNAB do something naughty? Probably not. Will Plaid? Probably not. Will they sell my information without me knowing? Probably. Will they ensure my account information is safe? Maybe. Isn’t that reassuring?
Instead, this needs to be a desktop app — this can’t be a web app. I don’t trust a shared server enough for this type of information. I want a program where the “bank crawling” is done on my machine. Not some arbitrary server somewhere, but my device. That’s significantly more secure than trusting a server somewhere in the universe.
But that means I can’t use my favorite technology — ASP.NET, or continue this Blazor experiment. It’s a web technology, but I don’t want this to be a web app. And no, Blazor WebAssembly isn’t going to solve this — that’s still a web app.
What I want is a native desktop application. But I’ve been enjoying Blazor, and I’m great at building quickly in HTML/CSS. Can I stick with it?
The Solution? Steve Sanderson to the Rescue
I began researching on a way to integrate Blazor into the desktop. After all, I know of Electron, but it seems asinine to wrap a .NET app into a JS wrapper for a Windows machine. And my initial experience with debugging an Electron app left quite a bit to be desired — although that part could be user error. What isn’t user error is the overall slowness and excessive RAM usage that Electron does.
I came across an interesting experiment Steve Sanderson wrote about. He called it WebWindow. As he tag lined his article:
It’s like Electron, but without bundling Node.js or Chromium, and without most of the the APIs.
In summary, WebWindow is a prototype (now dead) .NET web-rendered UI alternative to Electron. Since .NET Core is cross-platform, you can write most of the container in .NET, and then wrap it in native code for the window. He’s good at C++ apparently, but I wouldn’t stand a chance at writing it and updating it. Maybe I’ll get to that point in the future…
Regardless, I pulled his example and began tinkering and experimenting myself. I actually had issues getting his Hello World example working, so I ended up tearing it apart and putting it back together. I wanted to maintain cross-platform capabilities, but I’m no Linux or Mac developer. Instead, in my experimenting, I kept the possibility of plugging in the Linux & Mac interface, but for now, I was going to focus on Windows.
In the end, I learned a lot from his implementation, but I went an alternative route with my implementation — which I’ll detail in the next couple of entries! Maybe at some point, I’ll remember that I want to write a money app, not a cross-platform native web viewer.