A lightweight, zero-dependency, configuration-driven HTTP/HTTPS proxy server with TLS termination, load balancing, and virtual hosts
npm install @skaznowiecki/node-proxy




> A lightweight, zero-dependency, configuration-driven HTTP/HTTPS proxy server with TLS termination, load balancing, and virtual hosts
- Repository: github.com/skaznowiecki/node-proxy
- CI/CD: Automated testing on Node.js 18.x, 20.x, and 22.x
- Test Coverage: 92%+ on core functionality
- License: MIT
- Maintained: Active development and maintenance
---
``bashGlobal installation (recommended for CLI usage)
npm install -g @skaznowiecki/node-proxy
🚀 Quick Start
$3
`bash
npm install -g @skaznowiecki/node-proxy
`$3
Create config.json:
`json
{
"80": {
"hosts": {
"myapp.local": "http://localhost:3000"
}
}
}
`$3
`bash
node-proxy start --rules config.json
`$3
Add to /etc/hosts:
`
127.0.0.1 myapp.local
`Visit: http://myapp.local/
---
📚 Progressive Learning Path
Learn by example, starting simple and building complexity.
$3
Use Case: Forward all traffic on a port to a single backend`json
{
"80": "http://localhost:3000"
}
`Routes all requests on port 80 to
http://localhost:3000.---
$3
Use Case: Route different URL paths to different backends`json
{
"80": {
"/api": "http://localhost:9000",
"/static": "http://localhost:8080",
"*": "http://localhost:3000"
}
}
`-
/api/* → API server (port 9000)
- /static/* → Static file server (port 8080)
- Everything else (*) → Main app (port 3000)---
$3
Use Case: Multiple domains on same port, different backends`json
{
"80": {
"hosts": {
"shop.example.com": "http://shop-backend:3000",
"blog.example.com": "http://blog-backend:4000",
"admin.example.com": "http://admin-backend:5000"
}
}
}
`Routes by hostname:
-
shop.example.com → Shop backend
- blog.example.com → Blog backend
- admin.example.com → Admin backend---
$3
Use Case: Distribute traffic across multiple backends`json
{
"80": {
"hosts": {
"api.example.com": {
"/": {
"type": "proxy",
"to": [
"http://api-server-1:9000",
"http://api-server-2:9000",
"http://api-server-3:9000"
]
}
}
}
}
}
`Requests are distributed round-robin across 3 API servers for high availability.
---
$3
Use Case: Full production configuration with TLS/SSL termination`json
{
"__defaults": {
"headers": {
"x_forwarded": true,
"pass_host": false
}
},
"80": {
"/": {
"type": "redirect",
"to": "https://example.com",
"status": 301
}
},
"443": {
"tls": {
"cert": "/etc/letsencrypt/live/example.com/fullchain.pem",
"key": "/etc/letsencrypt/live/example.com/privkey.pem"
},
"hosts": {
"www.example.com": {
"/": "http://frontend:3000",
"/api": {
"type": "proxy",
"to": ["http://api-1:9000", "http://api-2:9000"]
},
"/static": {
"type": "redirect",
"to": "https://cdn.example.com/static",
"strip_prefix": "/static",
"status": 301
}
}
}
}
}
`Production features combined:
- HTTPS/TLS: SSL termination with Let's Encrypt certificates
- HTTP → HTTPS: Automatic 301 redirect from port 80 to 443
- X-Forwarded Headers: Backend servers receive client IP and protocol info
- Load Balancing: API requests distributed across multiple servers
- CDN Redirect: Static assets offloaded to CDN
---
⚙️ Configuration Reference
$3
Enable HTTPS on any port by adding a
tls configuration:`json
{
"443": {
"tls": {
"cert": "/path/to/certificate.pem",
"key": "/path/to/private-key.pem",
"ca": "/path/to/ca-bundle.pem" // Optional
},
"*": "http://backend:3000"
}
}
`Key points:
-
cert: Path to SSL certificate (PEM format)
- key: Path to private key (PEM format)
- ca: Optional CA bundle for client certificate verification
- Works with Let's Encrypt, self-signed, or commercial certificates
- Combine with virtual hosts and all other routing featuresHTTP to HTTPS redirect:
`json
{
"80": {
"/": {
"type": "redirect",
"to": "https://yourdomain.com",
"status": 301
}
},
"443": {
"tls": { "cert": "...", "key": "..." },
"*": "http://backend:3000"
}
}
`$3
Enable proper client information forwarding to backends:
`json
{
"__defaults": {
"headers": {
"x_forwarded": true, // Add X-Forwarded-* headers
"pass_host": false // Forward original Host header
}
},
"80": "http://backend:3000"
}
`When enabled, the proxy adds:
- X-Forwarded-For: Client IP address (appends to existing header for proxy chains)
- X-Forwarded-Host: Original Host header from client request
- X-Forwarded-Proto: Protocol used (
http or https)These headers allow your backend application to:
- Know the real client IP address
- Determine if the original request was HTTPS
- Generate correct absolute URLs in responses
$3
Connection Keep-Alive (enabled by default):
- Reuses TCP connections to backend servers
- Reduces connection establishment overhead
- Significantly lowers latency for subsequent requests
- Configured with optimal settings:
- Max sockets per host: 100
- Max free sockets: 10
- Socket timeout: 60 seconds
Connection pooling happens automatically - no configuration needed. The proxy maintains separate connection pools for HTTP and HTTPS backends.
$3
#### 1. Proxy (Default)
Forward requests to backend server(s).
Single backend:
`json
{
"/api": "http://backend:9000"
}
`Multiple backends (load balancing):
`json
{
"/api": {
"type": "proxy",
"to": [
"http://backend-1:9000",
"http://backend-2:9000"
]
}
}
`With health checks (coming soon):
`json
{
"/api": {
"type": "proxy",
"to": ["http://backend-1:9000", "http://backend-2:9000"],
"health_check": {
"path": "/health",
"interval_ms": 5000,
"timeout_ms": 800,
"expect_status": [200, 204]
}
}
}
`#### 2. Redirect
HTTP redirect responses (301/302).
`json
{
"/old-path": {
"type": "redirect",
"to": "/new-path",
"status": 301
}
}
`With path stripping:
`json
{
"/static": {
"type": "redirect",
"to": "https://cdn.example.com",
"strip_prefix": "/static",
"status": 302
}
}
`Redirects
/static/image.png → https://cdn.example.com/image.png#### 3. Rewrite
Rewrite the URL path before proxying.
`json
{
"/api": {
"type": "rewrite",
"to": "/api/v2"
}
}
`Request to
/api/users → Proxied as /api/v2/users$3
Use
__defaults for global settings:`json
{
"__defaults": {
"timeout_ms": 30000,
"retry": {
"attempts": 3,
"backoff_ms": 1000
},
"headers": {
"x_forwarded": true,
"pass_host": true
}
},
"80": "http://backend:3000"
}
`$3
- Path wildcard:
"*" matches any path not explicitly defined
- Host wildcard: "*" matches any hostname not explicitly definedExample:
`json
{
"80": {
"hosts": {
"api.example.com": "http://api:9000",
"*": "http://default-backend:3000"
}
}
}
`---
🖥️ CLI Usage
$3
Before starting the proxy, validate your configuration file:
`bash
node-proxy validate --rules config.json
`Features:
- Comprehensive validation - Checks JSON syntax, port ranges, URLs, rule types, and required fields
- Warning detection - Identifies shadowed rules and non-standard redirect status codes
- Visual preview - Tree-format display of routing rules
- Quick feedback - Catch configuration errors before deployment
Example output:
`
[INFO] [Validate] Configuration is valid!Configuration Preview
=====================
Port 80
+-- Host: myapp.local
+-- Path: /
+-- [PROXY] -> http://localhost:3000
Summary: 1 port, 1 host, 1 rule
`$3
Start:
`bash
node-proxy start --rules config.json
node-proxy start --rules config.json --cluster --workers 4
`Stop:
`bash
node-proxy stop
`Restart:
`bash
node-proxy restart --rules config.json
`Status:
`bash
node-proxy status
`$3
Run with multiple worker processes for better performance:
`bash
node-proxy start --rules config.json --cluster --workers 4
`- Automatically restarts failed workers
- Distributes load across CPU cores
- Master process manages worker lifecycle
---
💡 Advanced Examples
All examples are in
src/__tests__/fixtures/:$3
- basic.json - Simplest proxy setup
- path.json - Path-based routing
- multi-hosts.json - Load balancing
- redirect.json - HTTP redirects
- rewrite.json - URL rewriting
- defaults.json - Global defaults
- health-check.json - Health checks (future)$3
- vhost-simple.json - Basic virtual hosts (Level 1)
- vhost-paths.json - Virtual hosts + path routing (Level 2)
- vhost-loadbalancing.json - Virtual hosts + load balancing (Level 3)
- vhost-mixed.json - Mixed routing types (Level 4)
- vhost-production.json - Production setup with SSL syntax (Level 5)$3
- vhost-microservices.json - API gateway for microservices
- vhost-development.json - Local development environmentView the complete files in
src/__tests__/fixtures/` for detailed examples.---
---
Want to contribute or run this project locally?
See the Development Guide for:
- Local development setup
- Running tests and code quality checks
- Project architecture and structure
- Contribution guidelines
- CI/CD pipeline details
---
MIT License - Copyright (c) 2026 Sergio Kaznowiecki
See LICENSE for full details.