The Problem

Many households still rely on legacy desktop tools (e.g., Microsoft Money) that are discontinued, expensive, or require cloud accounts. Users need a self‑hosted, zero‑dependency way to record accounts, transactions, and recurring items without learning a full‑stack framework.

What This Does

public/index.html loads the single‑page UI built from vanilla JavaScript files such as public/js/app.js, public/js/dashboard.js, and public/js/api.js. The UI talks to a lightweight Express‑style server defined in server/index.js. Server routes (server/routes/*.js) implement CRUD operations on JSON files stored under a data/ folder (created at first run). Configuration lives in server/config/paths.js (paths to the data directory) and server/config/defaults.js (default settings). Shared helpers in server/utils/helpers.js provide validation and file‑IO utilities used across most routes.

How It Is Wired

Execution begins with public/index.html → public/js/app.js → api.js which issues HTTP requests to server/index.js (started by npm start). server/index.js creates an HTTP server and attaches server/router.js. The router imports the most‑connected module server/config/paths.js (9 inbound imports, 0 outbound) and dispatches to route handlers:

Route filePrimary responsibilitiesOutbound imports
server/routes/accounts.jsList/create/update/delete accountshelpers.js, data.js
server/routes/categories.jsManage categories & subcategorieshelpers.js, data.js
server/routes/payees.jsCRUD for payeeshelpers.js, data.js
server/routes/recurring.jsSchedule recurring transactionshelpers.js, data.js
server/routes/transactions.jsRecord one‑off transactionshelpers.js, data.js
server/routes/backup.jsExport/import JSON backup fileshelpers.js, data.js
server/routes/settings.jsPersist UI settingshelpers.js, data.js
server/routes/transfers.jsMove funds between accountshelpers.js, data.js

All route files read/write the same JSON store via server/utils/data.js. The most‑connected module server/router.js imports nine other modules and forwards requests, giving it the widest blast radius: a change here can affect every API endpoint. No circular dependencies were detected, so the import graph is acyclic.

On the client, public/js/dashboard.js (986 lines) pulls aggregated data via /api/* endpoints and renders charts. The UI updates the JSON store through the same API, completing a full round‑trip from browser to file system in three hops: browser → api.js → server route → data.js.

How To Use It

# Quick one‑liner install (Ubuntu) – exact from README
curl -fsSL https://raw.githubusercontent.com/CoppingEthan/Brisk-Budget/main/deploy.sh | sudo bash

# Manual install
git clone https://github.com/moses-y/Brisk-Budget.git /opt/brisk-budget
cd /opt/brisk-budget
npm install
npm start          # runs server/index.js, listening on http://localhost:3000

The UI is reachable at http://localhost:3000. No environment variables are required; configuration is stored in the JSON data directory created automatically.

Real‑World Use

A family of four installs the app on a home Raspberry Pi. Each member accesses http://pi.local:3000 on their phone, logs daily expenses, and the dashboard shows net‑worth trends without any external service. Periodic backups are downloaded via the Backup page and stored on a NAS for disaster recovery.

Code Health & Issues

  • High – No test suite – 23 source files, zero test files.
  • High – No CI workflow – repository lacks any GitHub Actions or other CI config.
  • Medium – Dependabot missing – only package.json/package-lock.json present, no automated dependency updates.
  • Medium – Large binary in repo – public/images/bg.png (14.3 MB) should be moved to Git LFS or external storage.

Additional observations from the repository layout:

  • License file present (MIT).
  • npm lockfile present, confirming npm usage.
  • No Dockerfile, no .github/ CI definitions, and no test directory.

The Bottom Line

Brisk‑Budget delivers a functional, zero‑dependency personal finance tracker with a clear separation between a thin Express‑style API and a vanilla‑JS front end. The codebase is small enough for rapid onboarding but suffers from duplicated logic, deep nesting, and a lack of automated testing or CI. It is suitable for hobbyists or small households willing to accept the maintenance overhead of a manually‑tested, file‑based system.