Skip to content

Repository files navigation

Cathart — A private voice journal

A privacy-first AI voice journaling web app. Record your thoughts, get AI transcription + reflection, and keep everything on your device.

Features

  • Voice recording via MediaRecorder API with real-time countdown
  • AI transcription via Groq Whisper
  • AI reflection — a warm second-person response generated by Llama 3.3 70B
  • Local storage only — all journal entries live in your browser's IndexedDB (Dexie)
  • Daily minute quotas — 20 min/user/day, 200 min/day global cap tracked in Upstash Redis
  • No login, no accounts — anonymous UUID + IP-based identity
  • Hard cost cap — ~$5–7/month at max usage (well under $12)

Setup

1. Clone & install

git clone <repo>
cd cathart
npm install

2. Set environment variables

Copy .env.local.example to .env.local and fill in your keys:

cp .env.local.example .env.local
Variable Where to get it
GROQ_API_KEY console.groq.com — free tier available
UPSTASH_REDIS_REST_URL console.upstash.com — free tier sufficient
UPSTASH_REDIS_REST_TOKEN Same as above

3. Run locally

npm run dev

Deployment

Vercel (recommended)

  1. Push to GitHub
  2. Import to vercel.com
  3. Add the three env vars in Project Settings → Environment Variables
  4. Deploy

Render

  1. New Web Service → connect repo
  2. Build command: npm run build
  3. Start command: npm start
  4. Add env vars in the Render dashboard

Architecture

app/
  page.tsx              — main UI (recording + history)
  api/
    quota/route.ts      — GET quota status for a user
    transcribe/route.ts — POST audio → transcript (checks + increments quota)
    reflect/route.ts    — POST transcript → AI reflection

components/
  QuotaBar.tsx          — daily minutes remaining bar
  RecordButton.tsx      — record / stop button with live timer
  JournalEntryCard.tsx  — expandable past entry card

hooks/
  useRecorder.ts        — MediaRecorder lifecycle + auto-stop at quota limit
  useQuota.ts           — quota fetching

lib/
  db.ts                 — Dexie (IndexedDB) setup
  quota.ts              — Upstash Redis quota logic
  userId.ts             — anonymous UUID from localStorage
  ipHash.ts             — IP → SHA-256 hash (server-side)

Quota / cost model

Resource Limit Rationale
Per-user daily 20 min Encourages focused journaling
Global daily 200 min ~$2.40/day max Groq cost
Monthly ceiling ~$7/mo Groq Whisper + Llama at 200 min/day

Quotas reset at UTC midnight via key TTL expiry (48h Redis TTL).


Privacy

  • Audio and transcripts are processed by Groq's API transiently and not stored by the server
  • No journal content is written to any server-side database
  • All entries exist only in the user's browser (IndexedDB)
  • Redis stores only numeric minute counters keyed to an anonymous UUID+IP hash

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages