Local-first personal finance cleanup built with Next.js, React, TypeScript, and Tailwind CSS.
The app is aimed at a weekly workflow:
- upload exported bank or card CSV files
- categorize transactions locally
- review uncertain rows
- save corrections as reusable knowledge
Prerequisites:
- Node 20+
- Yarn 1.22+
cp .env.example .env
yarn install
yarn devOpen http://localhost:3000.
SpendLens uses database persistence only. Finance data is saved through the
server API into normalized PostgreSQL tables. DATABASE_URL is server-only; do
not expose it with a NEXT_PUBLIC_ prefix, and do not call Supabase or Railway
directly from client components. The app creates its normalized SpendLens tables
on first use through /api/finance-store.
For any PostgreSQL provider, set:
NEXT_PUBLIC_FINANCE_STORE_MODE=database
DATABASE_URL=postgresql://USER:PASSWORD@HOST:PORT/DATABASEFor hosted auth with Supabase, also set:
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=your-supabase-publishable-keyURL-encode special characters in the username/password before putting the value
in .env.
For Supabase:
- Create or open a Supabase project.
- Copy the PostgreSQL connection string from the database settings.
- Put that value in
.envasDATABASE_URL. - Use a URI that is reachable from where Next.js is running. For local development, that means a public or pooled connection string, not an internal cloud-only hostname.
- Keep or append
?sslmode=requirewhen the copied URI does not already include an SSL mode.
SpendLens uses Supabase's PKCE OAuth flow. To enable the Google button:
- In Supabase, open Authentication → Providers → Google and copy the
displayed callback URL. It has the form
https://PROJECT_REF.supabase.co/auth/v1/callback. - In Google Cloud Console, create a Web application OAuth client and add that Supabase callback URL under Authorized redirect URIs.
- Copy the Google client ID and client secret into the Supabase Google provider
settings and enable the provider. Do not put the Google client secret in the
SpendLens
.envfile. - In Supabase Authentication → URL Configuration, add each SpendLens
callback URL that may receive the completed login:
http://localhost:3000/auth/callbackhttp://localhost:3001/auth/callbackhttps://your-production-domain.example/auth/callback
For Railway:
- Add a PostgreSQL service to the Railway project.
- When the app is deployed on Railway, set
DATABASE_URLto Railway's PostgresDATABASE_URLvariable. The private/internal URL is preferred when the app and database are in the same Railway project. - For local development against Railway's hosted database, use Railway's public PostgreSQL connection URL because your machine cannot use Railway private networking.
- If the public connection requires TLS, append
?sslmode=require.
Local PostgreSQL works too:
NEXT_PUBLIC_FINANCE_STORE_MODE=database
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/spendlensThe app includes CSV import, local Ollama categorization, transaction review, import history/review, settings, statistics, and PostgreSQL persistence.