- Node.js 22+ (tested with v22.20.0)
- Claude Code with an active Claude subscription (
claudecommand in PATH) for AI features - YNAB account with personal access token
- SQLite (bundled via better-sqlite3, no separate install)
git clone git@github.com:ronilaukkarinen/dough.git
cd dough
npm installCopy the example env file:
cp .env.local.example .env.localEdit .env.local:
SESSION_SECRET— random string for JWT signingYNAB_ACCESS_TOKEN— optional, can be set via settings UI insteadYNAB_BUDGET_ID— optional, can be set via settings UI insteadCLAUDE_PATH— path to claude CLI binary, defaults toclaudein PATH
Set env vars and run the seed script:
USER1_EMAIL=yourname USER1_PASSWORD=yourpassword USER1_NAME="Your Name" \
USER2_EMAIL=partner USER2_PASSWORD=partnerpassword USER2_NAME="Partner" \
npx tsx scripts/seed.tsnpm run build
npm start -- -p 3001The app runs at http://localhost:3001.
- Log in with the credentials you set in the seed script
- Go to settings and connect YNAB (paste your personal access token)
- Select your budget
- Set your name, household size, and link your spending account
- Add income sources and recurring bills
To expose the app publicly:
cloudflared tunnel create dough
cloudflared tunnel route dns dough your-domain.example.comCreate a config file at ~/.cloudflared/config-dough.yml:
tunnel: <tunnel-id>
credentials-file: ~/.cloudflared/<tunnel-id>.json
ingress:
- hostname: your-domain.example.com
service: http://localhost:3001
- service: http_status:404Create user services for auto-start:
# ~/.config/systemd/user/dough.service
[Unit]
Description=Dough personal finance app
After=network-online.target
Wants=network-online.target
[Service]
WorkingDirectory=/path/to/dough
ExecStart=/path/to/node node_modules/.bin/next start -p 3001
Restart=on-failure
RestartSec=2
TimeoutStopSec=5
KillMode=mixed
Environment=NODE_ENV=production
[Install]
WantedBy=default.targetsystemctl --user enable dough
systemctl --user start doughThe SQLite database lives at data/dough.db. Back it up regularly:
sqlite3 data/dough.db ".backup /path/to/backup/dough-$(date +%Y%m%d).db"