Because "bahala na" is not a financial plan.
A collaborative budget tracking Progressive Web App. Create shared budget sheets with your household, track expenses and income by category, set budgets, and stay on top of your finances — even offline.
- Shared sheets — Invite collaborators with owner, editor, or viewer roles
- Category budgets — Set spending limits per category with visual progress tracking
- Expense & income tracking — Log transactions with category, payment method, date, and description
- Monthly overview — See how each category is trending for any month and year
- Recurring transactions — Set up repeating income or expenses (salary, subscriptions, etc.)
- Multi-currency — Each sheet has its own currency from 100+ supported options
- Offline-first — All write operations are queued locally and synced when back online
- Installable PWA — Add to home screen on Android and iOS for a native app experience
| Layer | Technology |
|---|---|
| Framework | React 19 + TypeScript |
| Build | Vite 6 |
| Routing | TanStack Router (file-based) |
| Server state | TanStack Query (with localStorage persistence) |
| UI | Mantine 7 |
| Backend / Auth / DB | Supabase (PostgreSQL) |
| PWA | vite-plugin-pwa + Workbox |
| Hosting | Vercel |
- Node.js 18+
- A Supabase project
git clone https://github.com/your-username/waldas-watch.git
cd waldas-watch
npm installCopy the example file and fill in your Supabase credentials:
cp .env.development.example .env.developmentVITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_PROJECT_REF_DEV=your-project-refFor production, create .env.production with the equivalent production project values (add SUPABASE_PROJECT_REF_PROD).
npm run devApp runs at http://localhost:5173.
| Script | Description |
|---|---|
npm run dev |
Start development server |
npm run build |
Production build to dist/ |
npm run preview |
Preview production build locally |
npm run typecheck |
TypeScript type check (no emit) |
npm run db:link:dev |
Link Supabase CLI to dev project |
npm run db:link:prod |
Link Supabase CLI to prod project |
npm run db:push:dev |
Push migrations to dev |
npm run db:push:prod |
Push migrations to prod |
npm run db:list |
List all migrations |
npm run functions:deploy:dev |
Deploy Edge Functions to dev |
npm run functions:deploy:prod |
Deploy Edge Functions to prod |
The app is hosted on Vercel. Deployments are triggered automatically on push to main.
Manual deploy:
npm run build
# then push to your connected Vercel projectvercel.json handles SPA routing rewrites and ensures sw.js is served with no-cache headers so PWA updates propagate immediately after each deployment.
src/
├── routes/ # File-based routes (TanStack Router)
│ ├── __root.tsx # Root layout (offline/sync/install banners)
│ ├── login.tsx
│ ├── signup.tsx
│ ├── invite/ # Accept sheet invites via token
│ └── _auth/ # Protected routes
│ └── sheets/
│ └── $sheetId/
│ ├── index.tsx # Dashboard
│ ├── add-transaction.tsx
│ ├── overview/ # Category breakdown
│ └── settings/ # Sheet settings, categories, members
├── components/ # Shared UI components
├── queries/ # TanStack Query hooks (read + mutation)
├── lib/ # Supabase client, API request functions, offline queue
├── hooks/ # Custom React hooks
├── providers/ # SessionProvider, QueryProvider
└── utils/ # Currency formatting, date formatting
Waldas Watch queues write operations (create/update/delete for transactions, categories, payment types, etc.) in localStorage when the device is offline. When connectivity is restored, queued operations replay automatically. A banner in the UI shows the current sync state and lets users manually retry failed syncs.
Android: Open the app in Chrome → tap the browser menu → Add to Home Screen.
iOS: Open the app in Safari → tap the Share button → Add to Home Screen.
Once installed, the app runs in standalone mode with no browser chrome. Updates are delivered automatically the next time you open the app after a new deployment.
Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)
You are free to share and adapt this code for non-commercial purposes, provided you give appropriate credit. Commercial use is not permitted.