A production-ready Express.js API server for interacting with OpenRouter's LLM API.
- β Helmet middleware for security headers
- β CORS origin restrictions in production
- β
Rate limiting on
/api/chatendpoint - β Server timeouts configured
- β Docker containerization support
- β Environment-based configuration
- β Health check endpoint
- Node.js 20+ (or Docker)
- OpenRouter API key
Copy env.example to .env and configure:
cp env.example .envRequired variables:
OPENROUTER_API_KEY- Your OpenRouter API keyALLOWED_ORIGINS- Comma-separated list of allowed CORS origins (production only)NODE_ENV- Set toproductionfor production deploymentPORT- Server port (default: 3000)OPENROUTER_DEFAULT_MODEL- Default model to use (default: x-ai/grok-4.1-fast)
# Install dependencies
npm install
# Run in development mode
npm run dev
# Build for production
npm run build
# Run production build
npm start# Build and start the container
docker-compose up -d
# View logs
docker-compose logs -f
# Stop the container
docker-compose down# Build the image
docker build -t openrouter-express-starter .
# Run the container
docker run -d \
--name openrouter-express-starter \
-p 3000:3000 \
--env-file .env \
openrouter-express-starter-
SSH into your VPS
ssh user@your-server-ip
-
Install Docker and Docker Compose
# Ubuntu/Debian curl -fsSL https://get.docker.com -o get-docker.sh sh get-docker.sh sudo usermod -aG docker $USER # Install Docker Compose sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose
-
Clone your repository
git clone https://github.com/Shriansh2002/openrouter-express-starter.git cd openrouter-express-starter -
Create
.envfilecp env.example .env nano .env # Edit with your values -
Start the application
docker-compose up -d
-
Set up reverse proxy (NGINX)
server { listen 80; server_name yourdomain.com; location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; # Timeouts proxy_connect_timeout 30s; proxy_send_timeout 30s; proxy_read_timeout 30s; } }
-
Install Node.js 20+
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt-get install -y nodejs -
Clone and build
git clone https://github.com/Shriansh2002/openrouter-express-starter.git cd openrouter-express-starter npm ci npm run build -
Set up PM2 for process management
npm install -g pm2 pm2 start dist/server.js --name openrouter-express-starter pm2 save pm2 startup # Follow instructions to enable auto-start -
Configure environment variables
cp env.example .env nano .env
- Helmet: Sets various HTTP headers for security
- CORS: Restricted origins in production mode
- Rate Limiting: 50 requests per 15 minutes per IP (production)
- Timeouts: 30s request timeout, 65s keep-alive timeout
- Non-root user: Docker container runs as non-root user
Send a chat request to the LLM.
Request Body:
{
"messages": [
{
"role": "user",
"content": "Hello, how are you?"
}
],
"model": "x-ai/grok-4.1-fast", // optional
"stream": false // optional, currently not supported
}Response:
{
"model": "x-ai/grok-4.1-fast",
"message": {
"role": "assistant",
"content": "I'm doing well, thank you!"
},
"usage": {
"prompt_tokens": 10,
"completion_tokens": 8,
"total_tokens": 18
}
}Health check endpoint.
Response:
{
"status": "ok"
}- Production: 50 requests per 15 minutes per IP
- Development: 100 requests per 15 minutes per IP
Rate limit headers are included in responses:
RateLimit-Limit: Maximum requests allowedRateLimit-Remaining: Remaining requests in current windowRateLimit-Reset: Time when the rate limit resets
The application includes a health check endpoint at /health that can be used with monitoring tools or load balancers.
MIT