How a Google Sheet became Vector

I wanted digital envelope budgeting I could work with throughout the month. Building it took a spreadsheet, several redesigns, and a lot of testing.

JJ Lowery
Published Updated
vector-logo

Vector started as a Google Sheet.

I wanted a clearer way to decide what my money was for. Envelope budgeting made sense to me: assign money to a purpose, spend against that amount, and adjust when circumstances change. The difficulty was making that work digitally, with money sitting in accounts rather than physical envelopes.

I wasn't happy with the budgeting apps I'd tried, so I built my own envelope system in Google Sheets. I upgraded the sheet several times, worked through several design iterations, and eventually used AI and large language models to build Vector.

The spreadsheet came first

The sheet was already a functional budgeting system. It let me work with planned spending, actual spending, and what remained. Leftover money could be given another job in an envelope or returned to an account.

That mattered because a budget changes throughout the month. You make a plan, something costs more or less than expected, and then you have another decision to make. I wanted the system to help with that ongoing work.

I kept upgrading the sheet. It could do a lot, but it was difficult to manage. Turning it into an app meant working out how to carry those budgeting ideas into an interface someone could use without managing the spreadsheet itself.

The old sheet also became a reference for the app's dashboard and envelope management. The budgeting model had a history before the application code did.

Working through the design

I went through several design iterations as Vector took shape. For a budget, the design needs to make clear what a number on the screen actually means.

An envelope can have an amount I plan to spend, an amount I've assigned to it, spending that's already happened, and a remaining balance. Those figures answer different questions. If the interface blurs them together, it's easy to mistake a plan for money available to spend. Assigning cash to envelopes organizes the budget while the money stays in its real account.

Income brought out the same problem. A paycheck can be expected on one date, arrive on another, and be intended to support a different month's budget.

Take a paycheck deposited on August 31 that you want to use for September. Its transaction date should stay August 31. The choice to use it for September belongs to the budget plan. Changing that choice shouldn't change the record of when the money arrived.

In Vector, expected income, received income, the month the money should support, and actual cash available to fund envelopes each have a separate role. An expected paycheck can help you plan. It can't supply cash before it arrives.

Working through those distinctions gave me rules I could explain and check. They also made the design questions more specific: which figure does this screen need, and what is the person allowed to change here?

Building with AI

AI and LLMs made it possible for me to turn the spreadsheet and designs into a much larger application. I use them to work through behavior and troubleshoot problems, and Codex writes the implementation code.

My work is defining what the system should do, explaining the workflows, finding the exceptions, and reviewing whether the result matches. A request like “add income planning” needs more detail before it's useful: what creates a real deposit, what stays an estimate, what happens when the amount changes, and what happens when a match is wrong?

Vector uses Supabase for its data, Vercel for deployment, and GitHub to manage changes. Pull requests and previews give the work a review point. The process has involved repeated implementation, testing, corrections, and redesign as the app has grown.

The requirements have grown more detailed along with it. Once a budgeting rule is written down, I can ask Codex to implement it and check the result against that rule.

Checking the work

The income tests make some of those rules concrete. One test starts with $2,000 received and another $1,500 expected. That supports a $3,500 monthly plan, while the cash available remains $2,000.

When the expected paycheck arrives at $1,300, the income supporting the plan becomes $3,300. The $3,500 spending plan stays visible, along with the $200 shortfall. The test checks that the actual amount replaces the estimate, rather than adding the two together or quietly reducing the spending plan.

Other checks cover assigning income to a future month, keeping an explicitly unmatched paycheck from being silently matched again, and funding envelopes only with actual available cash. These are small scenarios, but they reveal whether the numbers mean what the interface says they mean.

Testing has also exposed problems that had nothing to do with how a screen looked. In one Bank Activity investigation, an earlier check with 300 rows had stayed below the timeout. With roughly 1,004 rows and the full historical read path active, the feature failed.

A reproduction using synthetic data isolated a database helper that repeatedly scanned timezone information. A focused change reduced the measured helper time from about 11.1 seconds to 41.3 milliseconds while preserving its validation behavior. That measurement was for the helper, not the whole page.

I'm still testing and refining Vector. The app has grown a long way from the Google Sheet, and it has required a lot of decisions the sheet never had to handle. The question underneath it is still the one that got me started: what is this money for, and what needs to change when the plan meets reality?