Server Automation
in TypeScript
Write server automation recipes as functions and push them over SSH.
bun install -g @grovemotorco/ignition
import type { ExecutionContext } from "@grovemotorco/ignition"
import { createResources } from "@grovemotorco/ignition"
export default async function (ctx: ExecutionContext) {
const { apt, file, directory, service } = createResources(ctx)
await apt({ name: "nginx", state: "present" })
await directory({
path: "/var/www/app",
owner: "www-data",
mode: "755",
})
await file({
path: "/var/www/app/index.html",
content: "<h1>Hello from Ignition</h1>",
owner: "www-data",
})
await service({ name: "nginx", state: "started", enabled: true })
}
$ ignition run deploy.ts admin@web-1
web-1 ▸ Running deploy.ts
✓ apt nginx installed
✓ docker edge-cache started
✓ dir /var/www/app created
✓ file /var/www/app/index.html changed
✓ file /etc/nginx/sites-available/app.conf changed
✓ service nginx started
6 resources: 6 changed, 0 ok, 0 failed
completed in 3.4s
$ ignition run deploy.ts admin@web-1
web-1 ▸ Running deploy.ts
─ apt nginx ok
─ docker edge-cache ok
─ dir /var/www/app ok
─ file /var/www/app/index.html ok
─ file /etc/nginx/sites-available/app.conf ok
─ service nginx ok
6 resources: 0 changed, 6 ok, 0 failed
completed in 1.1s ── nothing to change
TypeScript Recipes
Write server automation logic in real TypeScript. No YAML, no DSL. Get full IDE autocomplete, type checking, conditionals, loops, and async/await. Import any npm package. Or use AI to write the recipe for you.
import type { ExecutionContext } from "@grovemotorco/ignition"
import { createResources } from "@grovemotorco/ignition"
export default async function (ctx: ExecutionContext) {
const { apt, file, directory, service } = createResources(ctx)
await apt({ name: "nginx", state: "present" })
await directory({
path: "/var/www/app",
owner: "www-data",
mode: "755",
})
await file({
path: "/var/www/app/index.html",
content: "<h1>Hello from Ignition</h1>",
owner: "www-data",
})
await service({ name: "nginx", state: "started", enabled: true })
}
$ ignition run --check deploy.ts admin@web-1
web-1 ▸ Checking deploy.ts
✓ apt nginx ok
~ dir /var/www/app would create
~ file /var/www/app/index.html would change
✓ service nginx ok
4 resources: 2 would change, 2 ok
dry-run complete ── no changes applied
Check Before Apply
Every resource reads actual server state before mutating anything. Run ignition check for a complete dry-run. See exactly what would change before applying.
Real-Time Dashboard
Monitor automation runs in a local, live web UI. Watch resources check and apply in real time, expand output per host, and catch failures during runs.
Why Ignition?
This is real. It works.
TypeScript Recipes
Full language power. Loops, conditionals, type safety, and IDE autocomplete. No YAML.
Check Before Apply
Every resource reads actual state before mutating. Dry-run for free with ignition run --check.
Agentless
Nothing to install on target hosts. Uses your system SSH binary directly.
Idempotent
Run recipes repeatedly. Only what needs changing gets changed. Already correct? No-op.
Real-Time Dashboard
Monitor automation runs across hosts in a live web UI. See status as it happens.
Parallel Execution
Automate multiple hosts concurrently with a bounded worker pool.
How It Compares
You should probably use Ansible.
| Ignition | Ansible | Chef / Puppet | |
|---|---|---|---|
| Production Ready | Experimental | Yes | Does anyone still use it? |
| Language | TypeScript | YAML | Ruby / DSL |
| Agent required | No (SSH) | No (SSH) | Yes |
| State files | None | None | Server-side |
| Dry-run | Built-in | --check flag | --why-run |
| IDE support | Full (native TS) | Limited | Limited |