Ignitify.dev
One unit, one kernel

Your code gets its own kernel.

Untrusted code in its own Firecracker MicroVM. A warm VM can serve your next run.

You describe what the work is. Ignitify derives the machine it needs, boots it, and destroys it when the work is done.

01 — The console

You don’t configure a runtime. You describe a workload.

  1. You set seven axes

    Cardinality, duration, state, interaction, network, residency, storage. The VM size is a preset your plan allows.

  2. The platform derives the rest

    VM lifecycle, teardown, worker instructions, network, and the boot fingerprint.

  3. A garbage collector reclaims it

    When its work ends the VM is destroyed and its slot returned to the pool. A warm or pinned VM waits for your next run first.

You declaretask.yaml
your plannot in task.yaml · sets what you may use
run.presetchosen per run · sets RAM, CPU, default disk

cardinalityHow many units per VM?
durationHow long is one unit?
stateWhat survives between units?
interactionWhen do you need output?
network.typeWhat can the VM reach?
residencyWho owns the VM’s lifetime?
storage_mibScratch disk · a floor you can raise
MiB

Platform derivesyou never set this

Rejected at deploy

boot_fingerprint—
lifecycle—
loop shape—
on terminal—
network class—
heartbeat—
stream chunks—
reuse child—
vm size—
scratch drive—
plan disk cap—
task.yamlwhat you would write
02 — Blast radius

Containers share a kernel. This doesn’t.

Your code runs on its own kernel inside a MicroVM, and a warm VM can serve your next run. One tenant’s code cannot read another’s memory, reach another’s filesystem, or talk to another’s network — not because a policy forbids it, but because there is no shared surface to cross.

01

Separate kernel

Not a namespace on a shared one. A hypervisor boundary, not a container boundary.

02

Nothing shared

Its own uid, its own root filesystem, its own network path.

03

Verified, not assumed

Cross-tenant and guest→host traffic are dropped at the packet level.

03 — Writing a task

Two files to write. Export run. That’s the contract.

This is a complete, real task — the whole developer surface in one screen. The Node version has no imports; Go and Rust import a small bundled client. The starter also holds a package.json and its lockfile, so a Node task has four files to deploy.

task.yaml
schema_version: 1
slug: streaming-job
runtime: node

execution:
  cardinality: one
  duration: short
  state: independent
  interaction: continuous
  network:
    type: egress

build:
  system_packages: [ffmpeg, git]

run:
  payload:
    q: war
  timeout_sec: 15
index.ts
export async function run(payload, ctx) {
  const res = await fetch(
    `https://api.datamuse.com/sug?s=…`,
  );
  const json = await res.json();
  const top = json.map((w) => w.word).slice(0, 5);

  for (const [i, suggestion] of top.entries()) {
    ctx.chunk({ suggestion, i });
  }

  return { q: payload.q, count: top.length };
}
A real session
$ ignitify task:create streaming-job
✓ Task Registered
task_id      019fdebb-171e-7198-a812-a755d67e0aa2
resource_id  tsk_EZWekgdGJSLt

$ ignitify task:deploy streaming-job
✓ Deployment Created
deployment_id  019fdebb-199b-75cc-8a15-650f3de2c717
status         READY
reused         false
content_hash   sha256:fbb55da6adde4995…

$ ignitify task:run streaming-job
✓ Run Submitted
run_id       019fdebb-1ce5-7048-bc36-ce8821f02c08
status       PENDING

Content-addressed

Deployments are immutable and hashed. Unchanged source reuses the existing image.

Image integrity

The code image is read-only inside the guest. It is verified before boot, not trusted after it.

Secrets

Only secret names enter the upload. Values are injected at run time.

04 — Your toolkit

Start with nothing installed.

What you get today, and what is honestly still ahead.

Easy to start

Export run() — that is the contract. In Node and Python that is all — no client, no framework. Go and Rust import a small client that task:create copies in.

An SDK for logs, metrics and more — soon

Node.js, Python, Go & Rust

Pick a runtime in task.yaml. Go and Rust compile to a binary and run on the same task image — no separate runtime image to manage. A binary that needs a system library the image lacks is caught at deploy.

One CLI

ignitify — every task, deployment, run and secret from one command line.

Telemetry that leaves the box

Runs emit structured events to pluggable sinks.

Custom Observability — coming soon

Per-run timelines

Every run leaves a per-tenant, append-only timeline of what happened and when.

Visualizer — coming soon
05 — Many tenants, one host

One noisy tenant can’t take the host down with it.

Running this for other people is a different job from running it for yourself. The controls for that are first-class, not bolted on.

Tiers, not overrides

Every limit a tenant has comes from a tier they are granted. A one-off deal is a new tier.

Fair queueing

One tenant’s deploy storm cannot starve another’s build. The work queue claims fairly across tenants.

Honest capacity

Entitlement and room are separate ledgers, so “allowed” and “available” are never conflated.

06 — Deploy and scale

From your machine
to a MicroVM in one crossing.

  1. 01

    task:create

    Scaffolds task.yaml and an entry file. Add --local to stay fully offline.

    Reserves the slug and gives the task a stable id.

  2. 02

    task:validate

    Checks the execution nature and the seven axes against the platform's own rules.

    Nothing leaves your machine.

  3. 03the crossing

    task:deploy

    Uploads your source and lockfile as they are. Nothing is built on your machine.

    1. in its own microVM
    2. the result, hashed
    3. the image, by digest
  4. 04

    task:run

    Submits a job and returns its id at once.

    Boots a MicroVM against that image and executes your run().

  5. 05

    run:get

    Asks for the status and result.

    Returns the status, the result and the last streamed chunk.