The operating system for independent consultants: clients, projects, time, invoices, expenses, and cash runway in one calm ledger.
Sign in, load a sample practice, invoice unbilled hours, and see what is still owed before the month surprises you.
Freelancers lose money in the gap between work done and cash collected. Spreadsheets hide overdue invoices, unbilled hours, and tax set-asides. Daybook keeps those numbers on one page.
- Auth — Google, X, or email and password. Every row is scoped to the signed-in user.
- Clients & projects — People, retainers, hourly work, and fixed fees.
- Time — Log hours against a project. Billable entries become invoice lines.
- Invoices — Draft, send, mark paid, or void. Overdue is computed from the due date. Print-ready document view.
- Expenses — Software, travel, workspace. Optional client attachment.
- Overview — Outstanding AR, aging, unbilled value, tax set-aside, and a six-month collected-vs-spent chart.
- AI — Weekly briefing and payment reminders via xAI when
XAI_API_KEYis present. - Sample practice — One click loads a realistic Barcelona studio so the product is demoable immediately.
| Layer | Choice |
|---|---|
| App | TanStack Start (React 19, Vite 8, TypeScript) |
| UI | Tailwind CSS v4, Radix, Recharts |
| Auth | Better Auth (Google, X, email/password) |
| Data | Neon Postgres in production, PGLite in local preview |
| Deploy | Vercel (npm run build applies migrations) |
Server modules under src/lib/daybook/ are organized as a domain layer (profile, clients, projects, time, invoices, expenses) with authenticated server functions against Postgres.
npm install
npm run devThe app listens on port 8080. Leave DATABASE_URL unset to use the embedded database. Set DATABASE_URL to a Neon connection string for real Postgres.
npm test
npm run typecheck
npm run buildEnd-to-end (dev server already running):
npm run test:e2emigrations/0002_daybook.sql defines profiles, clients, projects, time_entries, invoices, invoice_lines, and expenses. Auth tables live in migrations/0001_auth.sql and are not edited.
Server functions use authMiddleware and filter every query by user_id. The client never sends an owner id. Invoice voids return attached time to the unbilled pool. Paid invoices cannot be voided.
Private practice software. Adapt it for your studio.