Remmy is a full-stack AI decision-coaching app designed to help users move from analysis paralysis to committed action.
The app runs a 9-stage decision workflow, uses an Express backend as a secure proxy to Anthropic, and a React frontend for the guided experience with gamification.
- Guided 9-stage decision workflow
- AI coaching with stage-aware prompts
- Gamification system (clarity points, levels, achievements, streaks)
- Persistent local progress via Zustand
- Input validation, rate limiting, CORS controls, and security headers
- PWA support (manifest + service worker)
- Frontend: React 19, Vite, Zustand, Axios
- Backend: Node.js, Express, Anthropic SDK
- Security: Helmet, CORS, express-rate-limit, express-validator
.
|- backend/
| |- src/
| | |- config/cors.js
| | |- middleware/security.js
| | |- routes/ai.js
| | |- server.js
| |- test/cors-config.test.js
| |- .env.example
| |- package.json
| |- Procfile
|- frontend/
| |- public/
| | |- manifest.json
| | |- sw.js
| |- src/
| | |- components/
| | |- pages/
| | |- services/
| | |- store/useRemmyStore.js
| |- test/sanitize.test.js
| |- .env
| |- package.json
- Node.js 20+ recommended
- npm
- Anthropic API key
- Install dependencies.
cd backend
npm install
cd ../frontend
npm install- Configure environment variables.
Create backend env from the example:
cd backend
cp .env.example .envSet ANTHROPIC_API_KEY in backend/.env.
Optional frontend env (frontend/.env):
VITE_API_URL=http://localhost:3001- Run backend and frontend in separate terminals.
Terminal 1:
cd backend
npm run devTerminal 2:
cd frontend
npm run dev- Open
http://localhost:5173.
ANTHROPIC_API_KEY: required; Anthropic API keySUPABASE_URL: required; Supabase project URL for token verificationSUPABASE_ANON_KEY: required; Supabase anon key for auth verification requestsPORT: backend port (default3001)NODE_ENV:developmentorproductionALLOWED_ORIGINS: comma-separated exact origins (production should include only your live domain(s), no wildcards)
Example:
ANTHROPIC_API_KEY=your_real_key
SUPABASE_URL=https://your-project-ref.supabase.co
SUPABASE_ANON_KEY=your_supabase_anon_key
PORT=3001
NODE_ENV=development
ALLOWED_ORIGINS=http://localhost:5173,http://localhost:4173VITE_API_URL: backend base URL (default fallback ishttp://localhost:3001)
npm run dev: run with nodemonnpm start: run with nodenpm test: run backend unit tests
npm run dev: run Vite dev servernpm run build: build production bundlenpm run preview: preview production buildnpm run lint: lint frontend codenpm test: run frontend unit test for sanitize helper
Base URL: http://localhost:3001
GET /health- Response:
{ "status": "ok" }
POST /api/ai/chat(requiresAuthorization: Bearer <supabase_access_token>)- Content-Type:
application/json
Request body:
{
"message": "I cannot decide between A and B.",
"stage": "intake",
"context": {
"decision": "Quit job or stay",
"gutChoice": "Quit",
"daysStuck": "1 month"
}
}Response body:
{
"reply": "...AI response..."
}Validation and limits:
message: required, max 2000 charsstage: required, must be one of the 9 valid stagescontext: optional object- API limiter: 30 requests / 15 min / IP
- AI limiter: 10 requests / 15 min / IP
The app progresses through these stages:
intakenarrowinggut_checkresistanceanxiety_analysisdeadlinecommittedimplementationcheckin
Each stage can send stage-specific context to backend AI prompting.
- Never commit real keys to Git
- Keep
backend/.envlocal only - Backend enforces:
- Helmet headers
- Origin-restricted CORS
- JSON body size limit (
10kb) - Rate limits
- Input validation
Backend:
cd backend
npm testFrontend:
cd frontend
npm test- Frontend can be deployed to Vercel
- Backend can run on any Node host (Procfile included)
- Ensure backend env vars are set in your deployment platform
- Set frontend
VITE_API_URLto your deployed backend URL
401/403from AI route:- Check
ANTHROPIC_API_KEY
- Check
- CORS errors:
- Verify
ALLOWED_ORIGINScontains the exact frontend origin for the current environment
- Verify
429responses:- You hit rate limits; wait and retry
- Frontend cannot reach backend:
- Confirm backend is running on expected port
- Confirm
VITE_API_URLmatches backend URL
Current project license is ISC (see backend/package.json).