Open Sourcing uFincs
Hack to your heart's content.
Today, on the one-year anniversary of announcing uFincs to the public, I am delighted to share that uFincs has now gone open source! This is something that I've wanted for uFincs since the very beginning, and I'm so happy to finally share it all with the world.
However, if you haven't been following along with the uFincs Update series on my personal blog, you might be wondering "Why would this guy go out of his way to open source what seems to be a totally viable startup?"
Hint: that last part was sarcasm.
Why am I Open Sourcing uFincs?
Frankly, there are a lot of different reasons for it. However, if I had to pare it down to just one, it'd be because I think there are other people who can make better use of uFincs than I can.
See, at this point in uFincs' life, it has already met and exceeded my personal use cases. uFincs is very much an app that I built to solve a personal want: I wanted a GnuCash that didn't look like it was from the late 90s and that worked across all of my devices. Obviously, being a web dev, that meant that uFincs would be a web app.
It also meant that uFincs would retain the core workflow of GnuCash — double-entry accounting where the vast majority of transactions are entered manually. There's just something about being so deeply on the pulse of one's finances that I enjoy.
However, if there's one thing that was thrown at me after launching uFincs, it's that this kind of workflow isn't for everyone. God knows how many people wanted bank syncing, for example (I explicitly am never doing bank syncing for uFincs).
As such, uFincs hasn't really changed all that much in the year since I first launched it. Sure, taking on a full-time job certainly didn't help, but I've added maybe one new major feature (import rules), and I've utterly failed to grow the customer base.
After talking to enough people, I realized that I can't personally satisfy everyone's different needs and that — maybe, just maybe — there aren't as many people out there that share my views. This is personal finances after all!
So, world, you now have one more personal finance app as an option. One that — just like I did — you can tinker with to get it just right.
Speaking of which, what exactly is there to tinker with? What on Earth have I just open-sourced?
What's being Open Sourced
In the uFincs repo, you'll find a number of different things.
In the services folder, you'll find the entire codebase for uFincs (with one notable exception — see below). The Frontend React app, the Backend Feathers API, the Postgres configuration — it's all there, along with the
docker-compose config necessary to quickly get everything up and running locally.
Obviously, open sourcing the codebase is kind of the bare minimum for this kind of announcement, so this should be no surprise. But it does mean that you can now jump in to add or tweak things to your heart's desire.
Of course, jumping straight into this kind of codebase probably isn't the easiest thing. Fortunately, you'll find that practically every noteworthy folder has its own
README for giving a quick (or sometimes even detailed) explanation of what's inside and what's important.
But that's just the
services folder! There's a heck of a lot more in the repo.
For instance, take the terraform folder. In here, you'll find all of the configuration for the production infrastructure that currently powers ufincs.com. Kubernetes cluster, monitoring, logging, networking... there's basically an overkill amount of infrastructure powering the simplest of web apps with practically no load whatsoever, but all of it has been open-sourced.
Then there's the helm folder. Want to deploy uFincs to your own Kubernetes cluster? Well, here are all of the templates you could ever need to base the manifests off of.
However, I'm not just open sourcing code and configuration here. Oh no, I'm doing something a little special: I'm making public the bulk of the technical docs that I wrote as part of designing and building uFincs. This ranges from things like playbooks for operating uFincs in production, to the UI concepts I put together for redesigning uFincs, to my train-of-thought design docs for developing individual features.
Want to know how to clear the Nginx cache on the Kubernetes cluster? There's a doc for that.
Want to know why I designed the Transactions page the way I did? There's a doc for that.
Together, these docs help provide a crucial amount of context and background knowledge for understanding not only the current uFincs codebase but why the codebase came to be the way it is. Personally, I think these are almost more interesting than the code itself, so I hope you enjoy them :)
But we're not done yet. There's still one last surprise that I'm open-sourcing...
API Proxy Prototype
You know how I said that a lot of people wanted bank syncing for uFincs, but that I'm staunchly anti-bank-syncing for personal finance apps?
Well, I'm really only staunchly anti-bank-syncing insofar as having to support it.
As such, I've put together a second repo with what I'm calling the API proxy prototype.
See, how uFincs works is that the Frontend app (i.e. the code running in the browser) encrypts all of the user data that is sent to the Backend API. This way, the only thing stored in the database is encrypted blobs of mumbo jumbo.
However, this setup makes it difficult to actually use the Backend API as... well, an API! If you can only push or pull encrypted data — and the Frontend is the only thing that knows how to deal with this encrypted data — then how are you supposed to use the API with some other client?
The answer is that you build a second client. One that you can actually interact with like you would a normal REST API.
What I'm calling the "API proxy prototype" is an Express API that has the same code for encrypting/decrypting data that the Frontend does so that it can correctly deal with all the encrypted data that the Backend exposes, while itself only exposing a simple REST API that deals with plaintext data. Which is to say, this is 'the' way for integrating external systems (e.g. bank syncing) with uFincs.
Of course, I'm calling it a "prototype" on purpose. The intent here is that it gives people who want to extend uFincs a clear path forward without me having to officially support whatever external integrations everyone wants. Take this prototype, extend it to fit your needs, maybe contribute something back if you think others could benefit, profit.
That's it. That's everything that's being open-sourced.
However, that's not the same as saying that everything has been open-sourced...
What's not being Open Sourced
Here comes the "one notable exception" from before...
Basically, it's just the marketing site. The service folder still exists in the public repo (for consistency reasons), but the code has been gutted out of it.
Why? Well, you can probably guess: I used a paid template for the marketing site. One that I definitely don't have a license to just open source willy-nilly. So — much to my own annoyance since I now have to maintain two separate repos — the marketing site code had to be removed and the public repo was chopped off at the latest commit.
To make up for losing all of the git history, I've opted to instead copy-pasta in the entire git log as part of the docs. Yes, all of the commit messages dating back to the original repo's very first commit. This is actually pretty cool since the majority of the commit messages document some rather specific implementation details, along with keeping a rolling record of introduced/discovered tech debt.
Certain Doc Images
However, the marketing site is not the only thing being not-open-sourced. If you go through enough of the technical docs, you'll likely come across some "[redacted]" text. This is primarily in the UI Concept docs since I've gone through and removed the images that I used for design inspiration.
This is more of a copyright thing than anything else. When I was redesigning uFincs, I was copying and pasting images from all over the place, without making sure to keep links to everything. So, to save myself that headache, I opted to just remove them.
Altogether, not too bad as far as having to scrub things.
When I first launched uFincs, I was questioned if I would ever open source it.
When I first had the idea for uFincs, that question had already been answered.
And now, that answer has been fulfilled. In the end, uFincs has been much more of a passion project than it has been a business, and that's ok.
As always, if you have any questions or comments, feel free to reach out to me at firstname.lastname@example.org. And if you want to use uFincs without having to self-host it, why not check out the pricy subscriptions at ufincs.com? :)
Till next time.