Skip to content

Documentation

Self-hosting guide

Costwatch is a Next.js app backed by Supabase (Postgres, Auth and Row Level Security). There is no other server to run. This guide takes you from a fresh clone to a deployed instance.

Requirements

  • Node.js 20.9 or newer
  • A Supabase project (the free tier is enough), or the Supabase CLI with Docker for a fully local setup

1. Create a Supabase project

Create a project at supabase.com. From Project Settings → API, copy the Project URL and the anon / publishable key.

You will never need the service_role key. Costwatch talks to the database only as the signed-in user, so Row Level Security is always enforced.

2. Set up the database

Clone the repository and push the migrations with the Supabase CLI:

git clone https://github.com/App-Chef/costwatch.git
cd costwatch
npx supabase login
npx supabase link --project-ref <your-project-ref>
npx supabase db push

Prefer not to use the CLI? Open the SQL editor in the Supabase dashboard and run each file in supabase/migrations in order.

For a local database instead, run npx supabase start and then npx supabase db reset. That also loads supabase/seed.sql: a demo account (demo@example.com / costwatch-demo) with made-up example data. Never load the seed into a production project.

3. Environment variables

Copy web/.env.example to web/.env.local and fill it in:

NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-or-publishable-key
NEXT_PUBLIC_SITE_URL=http://localhost:3000
NEXT_PUBLIC_AUTH_GOOGLE_ENABLED=false
  • NEXT_PUBLIC_SITE_URL is used for auth email links, the sitemap and social previews. Set it to your public URL in production.
  • NEXT_PUBLIC_AUTH_GOOGLE_ENABLED shows the Google button. Only turn it on after configuring the provider (below).

4. Configure authentication

In Authentication → URL Configuration, set the Site URL to your public URL and add these Redirect URLs:

http://localhost:3000/auth/callback
https://your-domain.com/auth/callback

Email/password and magic links work out of the box. Supabase's built-in email sender is heavily rate limited, so configure a custom SMTP provider before inviting real users.

Google (optional): create an OAuth client in Google Cloud Console with the authorized redirect URI shown in Authentication → Providers → Google, paste the client ID and secret there, then set NEXT_PUBLIC_AUTH_GOOGLE_ENABLED=true.

5. Run it

cd web
npm install
npm run dev

Open http://localhost:3000, create an account and add your first product.

6. Deploy

Any host that runs Next.js works. On Vercel, import the repository, set the root directory to web, add the environment variables above, and deploy. Remember to add your production /auth/callback URL to Supabase.

How the numbers work

  • Monthly cost is an estimate: the monthly equivalent of every active recurring cost. Yearly costs are divided by 12, quarterly by 3, and custom intervals by their length in months (using 365.25 days per year).
  • One-time costs are shown separately and are not part of the monthly cost.
  • Paused and inactive costs are kept but not counted.
  • Estimated profit = revenue recorded this month − monthly cost. Profit margin = profit ÷ revenue × 100. With no revenue, no margin is shown.
  • Currencies are never converted. Each product has a primary currency; costs and revenue in other currencies are listed but left out of totals, with a note saying so.
  • Renewals use the next renewal date you enter. If that date has passed, Costwatch projects the next one from your billing cycle and marks it as estimated.
  • Cost history is recorded automatically whenever a cost's price, billing cycle or status changes.

What Costwatch is not

Costwatch answers one question: how much does my product actually cost me? It is not accounting software. It does not do invoicing, taxes, payroll or bank connections, and nothing in it is financial advice.