# ready-checker

A lightweight, zero-dependency CLI tool to verify that your Node.js server starts correctly and responds to health checks.

Perfect for CI/CD pipelines, pre-deployment verification, and local development testing.

## Features

- Zero external dependencies (uses only Node.js standard library)
- Works with any HTTP server (http, Express, Fastify, Koa, etc.)
- Configurable health endpoint and timeout
- Retry support for flaky startups
- Multiple output formats (human-readable, JSON, silent)
- Config file support (JSON file or package.json)

## Installation

```bash
# Global installation
npm install -g ready-checker

# Or use with npx (no installation required)
npx ready-checker server.js
```

## Quick Start

1. Your server file should export your app instance (Express, Koa, http.Server, etc.):

```javascript
// server.js
const express = require('express');
const app = express();

app.get('/health', (req, res) => res.json({ status: 'ok' }));

module.exports = app;  // Just export - ready-checker handles .listen()
```

2. Run the check:

```bash
npx ready-checker server.js
```

## Usage

```bash
ready-checker <server-file> [options]
```

### Options

| Flag | Default | Description |
|------|---------|-------------|
| `--health <path>` | `/health` | Health endpoint path |
| `--timeout <ms>` | `1000` | Request timeout in milliseconds |
| `--retries <n>` | `0` | Number of retry attempts on failure |
| `--retry-delay <ms>` | `500` | Delay between retry attempts |
| `--json` | `false` | Output result as JSON |
| `--silent` | `false` | No output, only exit code |

### Examples

```bash
# Basic usage
ready-checker server.js

# Custom health endpoint
ready-checker server.js --health /api/health

# With timeout and retries
ready-checker server.js --timeout 5000 --retries 3 --retry-delay 1000

# JSON output for CI/CD parsing
ready-checker server.js --json

# Silent mode for scripts
ready-checker server.js --silent && echo "Server OK"
```

## Configuration

### Config File

Create `ready-checker.config.json` or `.readycheckerrc` in your project root:

```json
{
  "health": "/api/health",
  "timeout": 2000,
  "retries": 3,
  "retryDelay": 500
}
```

### Package.json

Add a `readyChecker` field to your `package.json`:

```json
{
  "name": "my-app",
  "readyChecker": {
    "health": "/health",
    "timeout": 3000,
    "retries": 2
  }
}
```

### Priority Order

Configuration is merged in this order (highest priority first):

1. CLI arguments
2. Config file (`ready-checker.config.json` / `.readycheckerrc`)
3. `package.json` `readyChecker` field
4. Default values

## Server Contract

### Option 1: Export your app (recommended)

Export your app instance - ready-checker calls `.listen()` for you:

```javascript
const express = require('express');
const app = express();

app.get('/health', (req, res) => res.json({ status: 'ok' }));

module.exports = app;
```

### Option 2: Use process.env.PORT

If your server already calls `.listen()`, use `process.env.PORT`:

```javascript
const express = require('express');
const app = express();

app.get('/health', (req, res) => res.json({ status: 'ok' }));

// ready-checker sets PORT automatically before requiring your file
app.listen(process.env.PORT || 3000);

module.exports = app;  // Export so ready-checker can close it
```

### Skipping Crons, Schedulers, etc.

ready-checker sets `READY_CHECK=true` before requiring your file. Use this to skip non-essential services:

```javascript
const express = require('express');
const app = express();

app.get('/health', (req, res) => res.json({ status: 'ok' }));

// Skip crons and background jobs during health check
if (!process.env.READY_CHECK) {
  require('./cron-jobs');
  require('./queue-workers');
  connectToRedis();
  startScheduler();
}

app.listen(process.env.PORT || 3000);
module.exports = app;
```

### Supported Export Types

- **Express app** - `module.exports = app`
- **Koa app** - `module.exports = app`
- **http.Server** - `module.exports = http.createServer(handler)`
- **Request handler** - `module.exports = (req, res) => { ... }`
- **Fastify** - `module.exports = app`
- **NestJS** - Export the app instance
- **Hapi** - `module.exports = server`

See the `examples/` folder for implementation examples.

## Exit Codes

| Code | Meaning |
|------|---------|
| `0` | Success - server started and health check passed |
| `1` | Failure - server failed to start or health check failed |

## Output Examples

### Default Output

```
✅ Server started on port 54321
✅ Health check passed (GET /health → 200)
```

### With Retries

```
✅ Server started on port 54321
⚠️  Attempt 1/3 failed, retrying in 500ms...
⚠️  Attempt 2/3 failed, retrying in 500ms...
✅ Health check passed (GET /health → 200) [attempt 3/3]
```

### JSON Output

```json
{
  "success": true,
  "port": 54321,
  "status": 200,
  "elapsed": 45,
  "attempts": 1
}
```

### Failure Output

```
✅ Server started on port 54321
❌ Health check failed (GET /health → 500)
```

## Use Cases

### CI/CD Pipeline

```yaml
# GitHub Actions example
- name: Verify server starts
  run: npx ready-checker server.js --timeout 5000 --retries 3
```

### Pre-commit Hook

```bash
#!/bin/sh
npx ready-checker server.js --silent || exit 1
```

### Docker Health Check

```dockerfile
HEALTHCHECK CMD node -e "require('./server.js')(3000)" || exit 1
```

## License

MIT

