Express.js backend with Clerk authentication and Supabase PostgreSQL.
# Install dependencies
npm install
# Copy environment template
cp .env.example .env
# Edit .env with your actual keys
# Run development server
npm run dev| Variable | Description | Where to Get |
|---|---|---|
PORT |
Server port (default: 3001) | - |
NODE_ENV |
Environment (development/production) | - |
CORS_ORIGIN |
Frontend URL for CORS | Your frontend URL |
CLERK_SECRET_KEY |
Clerk secret key (starts with sk_) |
Clerk Dashboard > API Keys |
CLERK_JWT_PUBLIC_KEY |
JWT public key for local verification (recommended for production) | Clerk Dashboard > API Keys > Show JWT Public Key |
SUPABASE_URL |
Supabase project URL | Supabase Dashboard > Settings > API |
SUPABASE_SERVICE_ROLE_KEY |
Service role key (secret!) | Supabase Dashboard > Settings > API |
Setting this variable enables local JWT verification without network calls to Clerk's JWKS endpoint. This prevents TypeError: fetch failed errors that can occur on platforms like Render or Railway.
Accepted formats:
- Multi-line PEM (if your hosting supports it)
- Single-line with
\nescape sequences (most common)
The middleware automatically normalizes escaped newlines, so both formats work.
GET /api/health- Health checkGET /api/health/deps- Dependency health check (Supabase reachability)
GET /api/me- Get current user infoGET /api/opportunities- List all opportunitiesGET /api/opportunities/:id- Get single opportunityPOST /api/opportunities- Create opportunityPUT /api/opportunities/:id- Update opportunityDELETE /api/opportunities/:id- Delete opportunityGET /api/analytics- Get analytics data
# Health check (no auth needed)
curl http://localhost:3001/api/health
# Get opportunities (requires token)
curl -H "Authorization: Bearer YOUR_CLERK_TOKEN" \
http://localhost:3001/api/opportunities
# Create opportunity
curl -X POST \
-H "Authorization: Bearer YOUR_CLERK_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Test Internship","category":"internship","status":"applied"}' \
http://localhost:3001/api/opportunities- Create a new Web Service on render.com
- Connect your GitHub repo
- Set Root Directory to
backend - Set Build Command to
npm install - Set Start Command to
npm start - Add environment variables in Render dashboard
- Update
CORS_ORIGINto your production frontend URL
backend/
├── src/
│ ├── server.js # Main entry point
│ ├── lib/
│ │ └── supabase.js # Supabase client
│ ├── middleware/
│ │ └── auth.js # Clerk JWT verification
│ └── routes/
│ ├── opportunities.js # CRUD routes
│ └── analytics.js # Analytics endpoint
├── .env.example # Environment template
└── package.json