Skip to main content

Local Development

This section describes how to run Cashlytics locally for development.

Prerequisites​

  • Node.js 24 (see .nvmrc; the engines field requires at least 22.14)
  • npm
  • Docker (runs PostgreSQL 16 for local development)
  • Git 2.32 or newer (the Husky pre-commit hook is installed by npm install)

Setup​

git clone https://github.com/aaronjoeldev/cashlytics-ai.git
cd cashlytics-ai
npm install
cp .env.example .env

.env.example uses the Docker network host postgres in DATABASE_URL. For local development, change it to localhost:

DATABASE_URL=postgresql://cashlytics:cashlytics_secret@localhost:5432/cashlytics

Also set AUTH_SECRET (for example openssl rand -base64 32); the app does not start without it. See Environment Variables for everything else.

Start Database and App​

./scripts/dev.sh

The script starts only the postgres service from docker-compose.yml (container cashlytics-postgres), waits until it accepts connections, applies the migrations with npm run db:migrate, and then runs npm run dev. Open http://localhost:3000.

Database Migrations​

The project uses versioned SQL migrations in drizzle/. Use these commands:

npm run db:migrate    # apply pending migrations
npm run db:generate # create a new migration after changing src/lib/db/schema.ts

Do not use npm run db:push for normal work. It bypasses the migration history and can leave your schema out of step with what the Docker image applies on startup.

Demo Data​

psql "$DATABASE_URL" -f scripts/seed-demo.sql

This deletes all data in the target database and creates the demo user demo@cashlytics.online with the password admin123456789. Never run it against a database with real data.

Commands​

CommandPurpose
npm run devDevelopment server
npm testUnit tests (node:test via tsx)
npm run typecheck / npm run lintTypeScript and ESLint
npm run format:checkPrettier check
npm run build / npm startProduction build and server
npm run e2e:up / npm run e2e:downStart / remove the end-to-end stack
npm run test:e2eEnd-to-end tests

npm run e2e:up builds the production image from your checkout and starts it with PostgreSQL, a Mailpit mail catcher, and a fake OpenAI API. npm run test:e2e resets that stack's database to the demo data and drives the app with Chrome (set CHROME_PATH if Chrome is not found).

Developer Expectations​

  • Keep TypeScript strict-mode compatible.
  • Use Server Actions for data mutations.
  • Keep schema and validation changes aligned.
  • Update documentation when feature behavior changes.