lazyserve
v1.0.3
Published
Wake your local server on demand via ngrok — sleep when idle, wake on request
Maintainers
Readme
LazyServe
Wake your local server on demand — sleep on idle, wake on request.
LazyServe sits between ngrok and your local server. When a request hits your public URL, it wakes your server, proxies the request, and then puts it back to sleep after a period of inactivity.
Internet → ngrok → LazyServe proxy → (wakes) → Your Server
← (sleeps after idle) ←How it works
- Placeholder proxy always listens on a port (tiny, near-zero CPU)
- ngrok points to the placeholder — your public URL is always alive
- When a request arrives and your server is sleeping → LazyServe starts it, waits until ready, then forwards the request
- When no requests arrive for N minutes → LazyServe kills your server
- Next request → cold start again (~2–5 seconds)
Install
# Clone and install
git clone https://github.com/you/lazyserve
cd lazyserve
npm install
npm run build
npm link # makes `lazyserve` available globallyOr run directly:
npx ts-node src/cli.ts "npm start" --port 3000Usage
lazyserve "<command>" --port <port> [options]Examples
# Node.js app
lazyserve "npm start" --port 3000
# Python Flask
lazyserve "python app.py" --port 5000 --idle 10
# Custom idle timeout (5 minutes)
lazyserve "node server.js" --port 3000 --idle 5
# With ngrok auth token and custom domain
lazyserve "npm start" --port 3000 --authtoken your_token --domain myapp.ngrok.io
# Specific ngrok region
lazyserve "npm start" --port 3000 --region euOptions
| Option | Default | Description |
|--------|---------|-------------|
| --port | 3000 | Port your real server runs on |
| --proxy-port | port + 1000 | Port for the placeholder proxy |
| --idle | 15 | Minutes of inactivity before sleeping |
| --authtoken | env | ngrok auth token (NGROK_AUTHTOKEN env also works) |
| --domain | — | Custom ngrok domain (paid plans) |
| --region | auto | ngrok region: us, eu, ap, au, sa, jp, in |
| --health-path | / | Path to health-check your server's readiness |
| --silent | false | Suppress output |
Environment Variables
NGROK_AUTHTOKEN=your_token_here lazyserve "npm start" --port 3000Port layout
:3000 ← your real server (starts/stops)
:4000 ← placeholder proxy (always running) ← ngrok points hereThe proxy port defaults to realPort + 1000. You can override with --proxy-port.
Cold start
When your server is sleeping and a request arrives, the caller experiences a delay (typically 2–5 seconds) while the server boots. After that, all subsequent requests are forwarded instantly.
To minimize cold start time:
- Keep your server startup fast
- Use
--health-pathto point to a lightweight endpoint so LazyServe knows when it's ready
Programmatic usage
import { lazyServe } from "lazyserve";
await lazyServe({
command: "npm start",
port: 3000,
idleTimeoutMinutes: 15,
authtoken: process.env.NGROK_AUTHTOKEN,
healthCheckPath: "/health",
});Architecture
┌─────────────────────────────────────────────────────┐
│ LazyServe │
│ │
│ ┌──────────┐ ┌───────────────┐ ┌──────────┐ │
│ │ ngrok │───▶│ Placeholder │───▶│ Server │ │
│ │ tunnel │ │ Proxy │ │ Manager │ │
│ └──────────┘ │ (Fastify) │ └──────────┘ │
│ │ │ │ │
│ │ - intercept │ spawn/kill │
│ │ - wake │ child_process │
│ │ - proxy │ │ │
│ └───────────────┘ ┌──────────┐ │
│ │ Your │ │
│ │ Server │ │
│ └──────────┘ │
└─────────────────────────────────────────────────────┘License
MIT
