Install and run
goofi is one binary with the app compiled into it. Two commands bring a fresh clone up, and there is never a third.
Prerequisites
Three tools, none of them goofi's: rustup, Node.js, and uv. The compiler version is pinned in rust-toolchain.toml at 1.97.1, so rustup fetches the
right one on the first build and there is nothing to choose.
# rustup, Node.js and uv must be on PATH.
# The Rust toolchain itself is pinned in rust-toolchain.toml (1.97.1),
# so rustup fetches the right one on the first build.
git clone https://github.com/dav0dea/goofi-pipe
cd goofi-pipe
git checkout rust-rewrite
cargo run -p goofi-init # once per clone
cargo run # prints the URLgoofi-init provisions every precondition cargo has and cannot provide for itself:
it builds the two Python interpreters, installs the goofi package into each,
installs the app's dependencies, and writes the cargo config that points pyo3 at the
free-threaded interpreter. That last one must happen before cargo starts, because
cargo reads .cargo/config.toml only at startup. It is idempotent, so re-run it
after a version bump.
cargo run then builds the app whenever a frontend source is newer than the last
bundle, and fails if it cannot. It will not fall back to the previous bundle:
one that does not match the binary around it is the wrong app. goofi serves the app and never
opens one: it prints the URL, and the opening is yours.
The nodes come with it
Everything goofi ships lives in node-bundles/, one directory per bundle, and every bundle is built at goofi's build time and embedded, the Rust
built-ins included. So cargo run carries all 67 types and there is
nothing to pass.
--extra-nodes adds a root of your own, scanned after the shipped bundles:
cargo run -- --extra-nodes ~/my-nodesgoofi-init installs every shipped bundle's requirements. At startup goofi checks
every scanned root's against both interpreters. A terminal is asked before anything is installed, and without one those nodes are simply unavailable rather than silently missing. See Bundles.
Without the app
GOOFI_HEADLESS=1 is --headless spelled as an environment variable, and
it applies to the build as well. Set for cargo build, it leaves the app out of the
binary entirely, so no Node.js is needed and the result is headless for life with no flag to
remember at every run.
GOOFI_HEADLESS=1 cargo build --release # the app is left out of the binary entirelyA headless instance serves the API alone: /control, /data, /term and /mcp. The app's routes are never mounted, and the layout op group goes with them.
What you get
This reference was generated from goofi 3.1.0 answering its own ops. That instance registered 57 ops and 67 node types: 47 in Rust and 20 in Python across 4 bundles, with 9 panel types and 6 viewer kinds.
- The CLI: flags, client mode, shell completions.
- The op vocabulary: every mutation goofi can make, as a phrase tree.
- The node reference: every shipped type, with its real source.
- Writing a node: the constants a file declares itself in.
This reference describes goofi 3.1.0(537cd394), generated from a running instance on 2026-09-06.