Package Exports
- @dreamxist/bal-cli
- @dreamxist/bal-cli/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@dreamxist/bal-cli) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@dreamxist/bal-cli
Command-line interface for Balance — opinionated personal finance with
delta = 0reconciliation.
bal is a thin TypeScript CLI that talks to a self-hosted Balance backend (Supabase + PostgreSQL + Edge Functions). It is read/write: list accounts, register transactions, manage API keys, and check whether your books are balanced — without leaving the terminal.
@dreamxist/bal-cli is just the client. To use it, you need a backend — see the self-hosting guide.
Install
npm install -g @dreamxist/bal-cliRequires Node 22+.
Quickstart
# Point the CLI at your backend
export SUPABASE_URL="https://<project-ref>.supabase.co"
export SUPABASE_ANON_KEY="<anon-public-key>"
# Authenticate with an API key minted from the web app
bal login --api-key bal_live_XXXXXXXXXXXXXXXX
# Show net position vs. accumulated transactions
bal balanceThe session is cached at ~/.balance/session.json (mode 0600) and refreshed automatically on every command.
Commands
Authentication
| Command | Description |
|---|---|
bal login --api-key <key> |
Exchange an API key for a JWT and persist a session. |
bal key create --name <label> |
Generate a new API key. Plaintext is shown once. |
bal key list [--include-revoked] |
List your API keys (never shows plaintext). |
bal key revoke <id|prefix> |
Revoke an API key by UUID or unique prefix. |
Transactions
| Command | Description |
|---|---|
bal add <amount> <category> --account <name|id> [--type] [--note] [--date] |
Register a transaction. Types: expense (default), income, refund, adjustment. |
bal transfer <amount> --from <name|id> --to <name|id> [--note] [--date] |
Move money between two accounts (does not affect accumulated). |
bal undo <tx-id> |
Reverse a transaction by creating a compensating adjustment (immutable ledger). |
bal list [--period] [--type] [--category] [--account] [--search] [--date-from] [--date-to] [--limit] |
List transactions. Period: day|week|month|quarter|year|all. --type accepts comma-separated values. |
bal balance [--json] |
Show position, accumulated, delta, and per-account balances. |
Accounts
| Command | Description |
|---|---|
bal account list [--archived] [--type] [--subtype] |
List accounts with balance and on-budget flag. |
bal account create <name> --type <asset|liability> --subtype <...> [--balance] [--credit-limit] [--entity] [--currency] [--off-budget] |
Create an account. |
bal account archive <name|id> |
Archive an account (soft delete). |
bal account rename <name|id> <new-name> |
Rename an account. |
bal account balance <name|id> <new-balance> |
Manually set a balance (typically for off-budget: investments, property). |
Debts (installment purchases)
| Command | Description |
|---|---|
bal debt list |
List active debts with progress. |
bal debt create <amount> <installments> <category> --account <name|id> |
Register an installment purchase. |
bal debt pay <debt-id|description> |
Pay one installment. |
bal debt payoff <debt-id|description> [--actual-amount] |
Pay off a debt entirely. |
bal debt archive <debt-id|description> |
Mark a debt as closed. |
Receivables
| Command | Description |
|---|---|
bal receivable pay <receivable> <amount> --to <account> |
Record a payment received from a receivable. |
Categories
| Command | Description |
|---|---|
bal category list [--entity] |
List categories. |
bal category create <parent-id> <id> <name> |
Create a subcategory under an existing parent. |
bal category rename <id> <new-name> |
Rename a category. |
bal category delete <id> |
Delete a category (fails if referenced by transactions). |
Recurring charges
| Command | Description |
|---|---|
bal recurring list [--include-inactive] |
List recurring charges. |
bal recurring create <name> <amount> --day <1-31> --category <id> --account <name|id> |
Create a recurring charge that auto-registers on day_of_month. |
bal recurring delete <id|name> |
Delete a recurring charge. |
Snapshots & export
| Command | Description |
|---|---|
bal snapshot create [--date] |
Capture a snapshot of current position (net worth, accumulated, delta). |
bal snapshot list [--limit] |
Show snapshot history. |
bal export [--format json|csv] [--output <path>] |
Export all data. |
Fintual integration
| Command | Description |
|---|---|
bal fintual sync [--dry-run] |
Pull latest Fintual prices and update off-budget account balances. |
SpA (business entity)
| Command | Description |
|---|---|
bal spa dashboard |
Show business accounts, monthly income/expenses, IVA due. |
bal spa invoice list [--direction emitida|recibida] [--month YYYY-MM] |
List invoices. |
bal spa invoice create --direction <d> --counterpart <name> --neto <amount> [--doc-type] [--folio] [--account] |
Create an invoice. |
bal spa invoice pay <invoice-id> --account <name|id> |
Mark an invoice as paid. |
bal spa f29 <YYYY-MM> |
Compute F29 summary for a given month. |
bal spa annual [year] |
Annual summary. |
Conventions
- Amount parsing: plain integers (
12000) or thousand-separated (12.000,12,000,12 000,12_000). All money is stored as integers (CLP in pesos, USD in cents). No decimals. - Account selection:
--accountaccepts UUID or a substring of the name (case-insensitive fuzzy match). Ambiguous matches error out. - JSON output: every read command accepts
--jsonfor machine-readable output. Useful for piping intojq, scripts, or other tools. - Transaction immutability: transactions are never updated or deleted. Corrections use
bal undo(creates a compensating adjustment).
Environment variables
| Var | Purpose | Required |
|---|---|---|
SUPABASE_URL |
Your Balance backend URL. | Yes |
SUPABASE_ANON_KEY |
Public anon key from the Supabase project. | Yes |
BAL_API_KEY |
Default API key for bal login (avoids passing --api-key). |
No |
BAL_EMAIL / BAL_PASSWORD |
Default credentials for bal key create/list/revoke (which require fresh password auth). |
No |
BAL_SESSION_FILE |
Override the session cache path (default ~/.balance/session.json). |
No |
VITE_SUPABASE_URL / VITE_SUPABASE_ANON_KEY |
Read as fallbacks for the two SUPABASE_* vars. |
No |
The CLI does not read .env files automatically. Use a tool like direnv or your shell profile to export the vars.
Backend setup
bal needs a Balance backend. Spinning one up takes ~30 minutes:
- Create a Supabase project.
- Push the migrations from the Balance monorepo (
supabase db push). - Deploy the Edge Functions (
auth-apikey,daily-charges,daily-backup,api-docs). - Set
CRON_SECRETand schedule the daily cron jobs. - Sign up via the web app and generate your first API key.
Full instructions: https://github.com/dreamxist/balance/blob/main/SETUP.md
Security notes
- API keys are SHA-256 hashed in Postgres. Plaintext is shown exactly once.
- Sessions are stored at
~/.balance/session.jsonwith mode0600. Treat that file as a secret. - The
auth-apikeyEdge Function is rate-limited (5 failed attempts per IP per 5 minutes). - All RPC calls use a user JWT, never
service_role. RLS enforces tenancy in the database.
For the full threat model and disclosure policy: https://github.com/dreamxist/balance/blob/main/SECURITY.md
Versioning
This package follows semver from 1.0.0 onward. Pre-1.0 releases may break between minor versions — pin if you script against bal --json outputs.
License
MIT © 2026 Francisco Zúñiga Palma.
Author
Built by Pancho Zúñiga. Building in public.
- LinkedIn:
- GitHub: https://github.com/dreamxist
- Twitter / X: