Skip to content

Service

The Service entity runs an arbitrary command as a subprocess using Bun.spawn. It supports environment variable injection, working directory configuration, HTTP readiness checks, and stdout/stderr streaming.

import { Service } from "sigil";
new Service(
name: string,
config: Omit<ServiceConfig, "name">,
interfaces?: EntityInterface[]
)
interface ServiceConfig {
name: string // Set via constructor
command: string[] // [executable, ...args]
cwd?: string // Working directory
env?: Record<string, string> // Environment variables (merged with process.env)
readyCheck?: {
url: string // HTTP endpoint to poll
interval?: number // Poll interval in ms (default: 1000)
timeout?: number // Max wait time in ms (default: 30000)
}
}
service.process: Subprocess | null

The Bun subprocess instance. null before start() is called.

Inherited from Entity. One of: "pending", "starting", "running", "stopping", "stopped", "error".

  1. Spawns the process via Bun.spawn(command, { cwd, env })
  2. Streams stdout and stderr to the terminal with [name] prefix
  3. If readyCheck is configured, polls the URL until a 2xx response
  4. Validates the process is still alive after startup

Sends SIGKILL to the subprocess.

env.add(
new Service("api", {
command: ["node", "server.js"],
cwd: "./backend",
env: { PORT: "3000" },
readyCheck: { url: "http://localhost:3000/health" },
})
);
env.add(
new Service("api", {
command: [
path.join(root, ".venv/bin/uvicorn"),
"main:app",
"--host", "0.0.0.0",
"--port", "8000",
],
cwd: path.join(root, "backend"),
env: { DATABASE_URL: db.connectionString },
readyCheck: {
url: "http://localhost:8000/health",
interval: 1000,
timeout: 30000,
},
})
);
import { Service, APIInterface, BrowserInterface } from "sigil";
// Backend API
env.add(
new Service("backend", backendConfig, [new APIInterface(8000)])
);
// Frontend SPA
env.add(
new Service("frontend", frontendConfig, [new BrowserInterface(3000)])
);

Service stdout and stderr are streamed to the terminal with a name prefix:

[backend] INFO: Uvicorn running on http://0.0.0.0:8000
[backend] INFO: Application startup complete
[frontend] VITE v5.0.0 ready in 150ms
[frontend] ➜ Local: http://localhost:3000/