How to build a YNAB alternative

How to build a YNAB alternative with accounts, categories, and typed-in transactions. Follow the prompts, check each step, then skip bank sync.

  • guide
  • vibe-coding
  • ynab

You can learn how to build a YNAB alternative as accounts, categories, and transactions you type yourself. YNAB is that product. The catalog line is “Give every dollar a job without giving a company your bank history.”

You pay $9.08–$14.99 a month. That is $109–$180 a year. The verdict is “Your budget, your rules”. The first estimate is 12 hours: accounts, categories, and manual transactions.

I already wrote the teardown, Build a YNAB alternative. This guide is the walk. Prompts in order, then what to look at.

The audience is one person or household who wants a private, hands-on spending plan. If you need bank connections, a shared household with invites, or a phone app that syncs while you shop, keep paying. The same v1 also replaces Monarch Money, Copilot Money, and Lunch Money if what you wanted was envelopes you enter by hand.

A receipt you photograph for reimbursement is Expensify, $5–$9 a person a month, about 12 hours. Who owes whom after a trip is Splitwise, $3.33–$4.99 a month, about 8 hours. Hours you bill a client are Harvest, $13–$17.50 a person a month. I walked that as How to build a Harvest alternative. Those hours wait until Ada pays.

How to build a YNAB alternative without bank sync

The YNAB page splits the work into three rows.

The first row is the one you want. Cash, checking, savings, and a credit card, each with a balance you can see. Monthly category groups with assigned, activity, and available. Transactions you type: payee, category, memo, cleared or not. That is the 12-hour v1.

The second row is 4 days. Funding targets, CSV import, reconciliation, reports. Do that after you have assigned a real paycheck by hand.

The third row is a month and up. Bank sync, mobile apps, shared budgets. Skip it.

If you tell an agent to “clone YNAB”, it aims at the third row. Pin every prompt to the first one.

v1 does this. Flavio opens Pocketplan, types a $1,000 paycheck from Bootcamp.dev into Arancio checking, assigns $700 to rent and $300 to groceries, then types $18.50 at Esselunga. Groceries show $281.50 left. The leftover opening sits in ready-to-assign until he gives it a job. A bank login and a second household member stay off the page.

The parts and where a request goes

Every product prompt ships in two flavors: Node.js plus Astro, and TanStack Start. The capability line for YNAB is Astro, HTMX, and D1. This site is an Astro app on Cloudflare, so that is the path I default to. Use TanStack Start if React is your weekday language. Pick one stack and stay on it.

The stack post is which tab you copy. The prompt post is how you pin the first estimate. The scope post is why bank sync waits.

Open Build your own YNAB. The guardrail is the useful sentence: store amounts as integer minor units, isolate every budget by owner, and never treat projections or category balances as financial advice. The non-goal sits next to it. No bank connections, no moving money, no investment advice, no tax filings, no second currency in the same budget.

FLAVIO'S BROWSER Setup, plan, register login required ASTRO APP ON THE REQUEST Save accounts, assign, type Recompute totals from rows D1 HOLDS THE LEDGER Budget, accounts, categories Transactions and assignments NOT IN V1 No bank API. No cron. No mail. CSV import waits for 4 days
One logged-in owner. Every total is recomputed on the request from the ledger.

A setup save, an assignment, and a typed spend are ordinary form posts. Nothing runs after the response. If the plan invents a Plaid worker or a nightly sync, send it back.

The data the budget carries

The card lists Budget, Account, CategoryGroup, Category, Transaction, and Target. Tonight you need those minus Target. Target is a funding goal. It belongs on the 4-day row.

Flavio owns one budget: a name, USD, and a pointer to the current month. The budget has accounts. Cash, checking, and savings are on-budget. A credit card is a debt account you can still type into. Each account starts with an opening balance you typed, stored as a row, not as a cached number on the account.

Category groups hold categories. Monthly holds Rent and Groceries. Wants holds Eating out. An assignment is one category, one month, one integer amount. A transaction is one account, a date, a payee, an integer amount, an optional category, a memo, and a cleared flag.

An inflow in October becomes ready to assign only in October. Assigning moves money from ready-to-assign into a category. Spending drops available. Assigned stays where you put it. A transfer is two linked account rows with no spending category. Deleting one side has to delete or flag the other.

BUDGET ACCOUNT checking, card GROUP Monthly, Wants TRANSACTION cents, date CATEGORY Rent, Groceries ASSIGNMENT category + month + cents TRANSFER PAIR two rows, no category TARGET 4-day row, not v1
One budget. Totals come from transactions and assignments. Targets wait.

Every amount is an integer in cents. Ready-to-assign, account working balance, category activity, and category available are derived. Nothing stores a running total. An edit writes a new input. It does not patch a cached sum.

One owner, one budget in v1. Isolate every query by ownerId. A guessed id from another account returns nothing: no category names, no amounts, no 404 that confirms the slug.

The screens you ship

Three surfaces. Keep them boxes and labels. If the agent starts matching YNAB’s live UI, send it back. Reports wait for the 4-day row, so Reflect is not a screen tonight.

The setup page is first. Budget name, USD, accounts with opening balances, two starter groups.

WIREFRAME · SETUP Pocketplan · USD Arancio checking opening $200.00 Savings · opening $0.00 Nexi card · debt $80.00 Groups: Monthly · Wants SAVE SETUP
Name, currency, opening rows. Cash openings can be assigned. Card debt cannot.

The monthly plan is the product. Previous and next month. Ready-to-assign at the top. Each category shows assigned, activity, available. You type into assigned. Moving money between categories is a later edit of those two assignments, and the budget total stays put.

WIREFRAME · OCT 2026 ‹ › Ready to assign $200.00 MONTHLY ASSIGNED AVAIL Rent $700.00 assigned · $700.00 left Groceries $300.00 · spent $18.50 · $281.50 Wants · Eating out $0.00
Ready-to-assign is the headline. Assigned, activity, available sit on each row.

The register is where you type. Newest first. Working balance is every transaction. Cleared balance is the ones you marked. Add inflow, spend, or transfer. Reconciliation, the ritual that locks those marks, sits on the 4-day row.

WIREFRAME · REGISTER Arancio checking Working $1,181.50 · Cleared $200.00 Oct 29 Esselunga −$18.50 Groceries · not cleared Oct 26 Bootcamp.dev +$1,000 Inflow · not cleared ADD TRANSACTION
The register is a list of rows you typed. Working and cleared are two sums of those rows.

Give every dollar a job

An envelope budget is money you have already received, split into jobs before you spend it. YNAB’s public method is zero-based. The site’s v1 is that method on a laptop you own.

Cash openings and inflows in the current month become ready to assign. Card debt does not. You give leftover dollars a category. Then you type the spend. Available falls. Assigned stays.

TYPE THE PAYCHECK INFLOW THIS MONTH? no: November stays empty READY TO ASSIGN $1,000 ASSIGN RENT AND FOOD $700 and $300, leftover $0 TYPE ESSELUNGA $18.50 OVERSPENT? yes: available goes negative GROCERIES $281.50 assigned stays $300.00 refresh still matches
Inflow, assign to zero, then spend. Available is assigned minus activity, every time.

Click into November and back. October still shows the same three numbers. A leftover available amount can roll into the next month by one explicit rule you write down. Overspending last month does too. If the agent invents a third rule in November, the plan is wrong.

Hours that later become an invoice stay in the Harvest guide. You paste Thursday’s total into Pocketplan only after Ada pays.

Prompt 1. Scaffold Pocketplan and stop

Copy the Astro prompt from the product page. Paste it into your coding tool. Put this block above it.

Ship the 12-hour row only.
Accounts, categories, manual
transactions.

Project name: Pocketplan.
Public URL is https://budget.flaviocopes.com.
Owner is Flavio.
One budget. Currency USD.

Seed accounts: Arancio checking
(opening $200.00), Savings
(opening $0.00), Nexi card
(debt $80.00).
Seed groups: Monthly (Rent,
Groceries), Wants (Eating out).

Do not add funding targets,
CSV import, reconciliation,
or reports.
Do not connect a bank, add
Plaid, build a mobile app,
or invite a second household
member. One currency only.

When the plan is done, stop.
Do not write code until I say go.

The official prompt already asks for a short technical plan first: routes, tables, authorization, jobs. Let it produce that plan. Read it.

You want /setup for the first save, /budget for the monthly plan, /accounts/arancio-checking for the register. Tables for budgets, accounts, category groups, categories, assignments, and transactions. No targets, no imports, no plaid_items, no household_members.

If the plan includes a bank login, a float amount column, or a cached ready_to_assign field, send it back. When the plan is narrow, say go.

What to check after the scaffold

Start the app. Sign in as Flavio. You should see setup, or an empty plan and a path to setup. Amounts are integers. There is no connect_bank route.

If the README is a placeholder, stop. It has to name integer cents, derived totals, owner isolation, and the sentence that the numbers are a ledger, not advice.

Prompt 2. Name the budget and open the accounts

Setup is a name, a currency, opening rows, and two groups. Agents skip this and dump you on an empty spreadsheet. The openings are the first ledger rows.

Build setup for Pocketplan.

Flavio opens /setup once.
Name the budget Pocketplan.
Currency is USD and cannot
change later.

Accounts tonight: cash,
checking, savings, credit
card. Each has a name and
an opening amount in cents.

Cash, checking, and savings
openings become ready to
assign in the starting month.
A credit-card opening is
debt. It does not become
ready to assign.

Create groups Monthly and
Wants. Monthly has Rent and
Groceries. Wants has Eating
out. Categories can be
renamed. They cannot be
deleted if a transaction or
assignment points at them.

Save writes the budget, the
accounts, the opening rows,
and the starter categories.
A second visit to /setup
edits names, it does not
mint a second budget.

Do not add a second currency
picker. Do not add a bank
connect button.

Done when Arancio checking
shows a $200.00 working
balance, ready-to-assign is
$200.00, and Nexi card shows
$80.00 of debt that did not
raise ready-to-assign.

What to check after setup saves

Save Pocketplan. /budget shows October, or whatever month you started in. Ready-to-assign is $200.00. Nexi still shows $80.00 owed.

Reload. Same numbers. Rename Groceries to Food shop. The category id stays. A second budget named Pocketplan is refused.

Open a private window as someone else, or with no cookie. /budget is a login wall. A guessed /accounts/arancio-checking shows nothing useful.

If ready-to-assign includes the card debt, the opening rule is wrong.

Prompt 3. Assign every leftover dollar

The first mini-prompt on the card is “Every dollar has a job, and it’s an integer”. Tonight that is the monthly plan.

Build the monthly plan for
Pocketplan at /budget.

Show the current month, with
previous and next. Ready to
assign sits at the top.
It is inflows and cash
openings for that month,
minus assignments for that
month. Derive it. Do not
store it.

Each category row shows
assigned, activity, and
available. Assigned is the
assignment row for that
month. Activity is spends
in that category in that
month. Available is assigned
minus activity.

Typing 700.00 into Rent
writes 70000 cents. A
partial dollar like 18.50
writes 1850. Reject a third
decimal. Never use a float
on the money path.

Moving $50 from Groceries
to Eating out changes those
two assignments. Ready to
assign does not change.

Leftover available rolls
into the next month by one
documented rule. Overspent
cash last month reduces
this month's ready-to-assign
by that same documented
rule. Write the rule in
the README.

A full recompute from the
raw rows must match the
screen after a refresh and
after month navigation.

Show a ledger, never advice
about what to buy.

Done when a $1,000 inflow
plus the $200 opening, then
$700 rent and $300 groceries,
leaves ready-to-assign at
$200.00, and November and
back still match a from-
scratch recompute.

The $200 leftover is the opening you have not assigned yet. Assign that too if you want a true zero. The card’s $1,000 scenario ignores the opening on purpose: $700 and $300 leave leftover zero.

What to check after the plan adds up

Type the Bootcamp.dev inflow first, or do prompt 4’s inflow and come back. Assign $700 to Rent and $300 to Groceries. Ready-to-assign is the leftover opening.

Refresh. Same cents. Click November. October’s assignments are gone from the grid, and ready-to-assign there starts from November inflows only. Click back. October is intact.

Assign $50 more to Groceries than you have. Ready-to-assign goes negative, or the field refuses. Pick one and write it down. A silent wrap to a huge integer means a float or an unsigned column leaked in.

If assigned plus available is stored on the category row, delete those columns. The screen has to survive deleting them.

Prompt 4. Type the register

A spend is a transaction on an account, pointed at a category. The third journey on the card can wait. Tonight you need inflow, spend, transfer, and a cleared toggle.

Build the register for
Pocketplan.

/accounts/arancio-checking
lists transactions newest
first. Show date, payee,
category, memo, amount,
cleared. Working balance
is every row. Cleared
balance is the marked ones.

Add an inflow with no
spending category. Add a
spend with a required
category. Add a transfer
to Savings or to Nexi.
A transfer writes two
linked rows and no
spending category.
Deleting or editing one
side updates the other
in the same request.

$18.50 at Esselunga is
1850 cents out of
Arancio checking, category
Groceries. Groceries
activity becomes 1850.
Available becomes assigned
minus 1850. Assigned stays.

Paying the Nexi card from
checking is a transfer.
It is not a Groceries
spend.

Cleared is a flag Flavio
toggles when the statement
agrees. Do not lock rows.
Do not write an adjustment.
That is reconciliation,
and it is the 4-day row.

A card spend still drops
the category. Do not build
the card-payment reserve
yet. That mini-prompt
waits with targets and
CSV.

Do not import a file.
Do not draw a chart.

Done when Esselunga shows
on the register, groceries
available is $281.50 after
a $300 assignment, a
transfer to Savings lands
on both registers, and
deleting the checking side
removes the savings side.

What to check after a real spend lands

Type Bootcamp.dev, $1,000, October 26, Arancio checking, inflow. Type Esselunga, $18.50, October 29, Groceries. The plan shows activity $18.50 and available $281.50 if you assigned $300.

Toggle cleared on the $200 opening. Working stays $1,181.50. Cleared becomes $200.00.

Transfer $40 to Savings. Checking falls $40. Savings rises $40. Ready-to-assign does not move. Delete the checking side. Savings loses its twin.

Hammer save on Esselunga. One row. If two rows appear, the agent treated the button as the only guard.

Failures the agent ships anyway

A float on the money path

0.1 + 0.2 is a debugging afternoon. You notice when $18.50 becomes 18.499999 after a refresh, or when ready-to-assign is 0.01 off. Integer cents, display with two decimal places.

A cached total that drifts

A balance column on accounts, or available on categories, will disagree after an edit. You notice when November looks fine and October’s leftover is wrong. Delete the cache. Recompute from the rows.

A Connect your bank button

Plaid-style logins, OAuth to every Italian bank, a feed that posts three days late with a mangled payee. That is a compliance product. The catalog puts it on the skip row so you have a sentence to paste. If plaid appears in the plan, you left the first estimate.

A one-legged transfer

Checking fell $40 and Savings did not rise. Or you deleted one side and the other stayed. Two rows, one link, one request.

Advice in the empty state

“You should assign more to Groceries” is not v1. The guardrail says the app shows a ledger. A red available number is enough.

Deploy the budget

Pocketplan wants Astro, HTMX, and D1. Put it on a subdomain you already own, budget.flaviocopes.com. D1 holds the ledger. There is no cron on the 12-hour row.

The hosting post is that path: the adapter, then the bindings, then the custom domain.

Attach the domain on the Worker. Sign in as Flavio from your phone on cellular. Type last month’s opening balances. Enter one paycheck. Assign it to zero. Type three spends you already made. Confirm ready-to-assign and the grocery available number still match a from-scratch recompute.

Take a D1 backup before you delete the paid account. The ledger is the history you will miss.

Use it as the real plan for a month. If you miss CSV import or a target, those are the 4-day row.

Then cancel YNAB, or Monarch Money, or Copilot Money, or Lunch Money, whichever one you pay for.

What to skip on purpose

Leave out bank connections, moving money, investment advice, tax filings, a second currency, native apps, and a shared household.

12-HOUR V1 Accounts and category groups Typed inflows and spends Ready-to-assign from the ledger SKIP THIS HALF Bank sync and Plaid logins Native mobile apps Shared household budgets
Ship the 12-hour ledger. Leave bank sync, apps, and shared budgets on the skip row.

Targets, CSV import, reconciliation, and reports wait until a paycheck you care about has been assigned by hand. The credit-card reserve mini-prompt lives there too. A $40 grocery charge on the card drops groceries by $40 and raises a card-payment category by $40. Paying the card is a transfer. I would not build that until the cash path is boring.

The first-project post still points at a tonight card. This is the weekend after that, when you still type groceries into someone else’s envelope.

A timesheet you already need is the Harvest guide. A numbered invoice after the week exists is FreshBooks, $23–$60 a month, about 10 hours. The FreshBooks teardown is that post.

More writeups land on the guides index. The audit is the catalog if you want a smaller first ship.

Start now

Go to Build your own YNAB. Copy the Astro prompt, or TanStack Start if that is what you write.

Tell the agent the first estimate only: accounts, categories, manual transactions. Twelve hours.

Assign one real paycheck until ready-to-assign is zero.

Related articles

Read all articles →