open source · bun · home assistant

Home automation you can type‑check.

Flowbun is a flow-based runtime in the spirit of Node-RED — except blocks are plain async TypeScript, wiring is diffable JSON on disk, and every wire is checked by tsc before anything runs.

data/wiring/blinds_sun_tracker.json — a real flow, running in a real house

Blocks are just TypeScript

Named, typed inputs and outputs on a plain async function. If you need a switch statement, you write a switch statement — no expression language, no palette of “switch” and “change” nodes.

Wires fail at compile time

Every flow compiles through a generated assertion file with realtsc. A wire carrying the wrong shape fails the reload — and the old flow keeps running untouched.

Effects live at the boundary

Only @hass/* blocks can touch Home Assistant, and each flow runs in its own process. A crash in one flow never takes down another — or your house.

A block is a file.

Blocks live in data/blocks/, one TypeScript module each. Wiring lives beside them as plain JSON — diffable, greppable, editable in your IDE. The runtime only ever reads it, and every write from any tool is auto-committed to its own git history.

State is three-scope SQLite, so a debounce timer survives reloads, restarts, and kill -9.

data/blocks/debounce.ts
import { defineBlock } from "flowbun";

export default defineBlock({
  name: "debounce",
  config: { ms: 30_000 },
  inputs: { signal: {} as { state: string; at: number } },
  outputs: { stable: {} as { state: string } },
  async process({ signal }, ctx) {
    const last = await ctx.state.block.get<number>("lastAt");
    if (last !== undefined && signal.at - last < ctx.config.ms) return;
    await ctx.state.block.set("lastAt", signal.at);
    return { stable: { state: signal.state } };
  },
});

The editor is optional sugar.

A browser canvas, Monaco with live typecheck errors on save, structured logs filtered per node, and an embedded Claude agent that edits flows through the exact same audited path you do. All of it is a plain websocket client of the same on-disk files — anything the editor can do, a curl script can do too.

The Flowbun editor: block palette on the left, a wired flow on the canvas, the Claude chat panel open on the right, and a live log panel along the bottom.

Wire something up.

Read the docsStar on GitHub