Docs · Getting started

Install on macOS

On a Mac, Nodeau runs models directly on the GPU through Metal. There is no Kubernetes, no Docker, no NVIDIA tooling and nothing that needs your password.

What a Mac can and cannot do#

Nodeau on Apple Silicon is qualified with named exclusions, and the exclusions are the honest half of that word.

On a Mac
Run a model on the GPU, with a local OpenAI-compatible endpointYes, through Metal
The curated catalog, downloads and SHA-256 verificationYes
Admission — predicting whether a model fits before starting itYes
Bring your own modelNot qualified. It builds and passes its checks on darwin; no Mac has run it, and it needs a cluster a Mac deliberately does not have
Join a fleetNo. A Mac runs standalone. It is not a Kubernetes node, and Nodeau will not pretend otherwise
Batch inferenceNo. Absent on darwin, and refused by name rather than half-working
Several GPUs in one machineNo. A Mac has one integrated GPU
Scheduling modes, power limits, fleet health and governanceNo. These are fleet capabilities and a Mac has no fleet

Requirements#

  • An Apple Silicon (M-series) Mac. Intel Macs are refused by name — Metal execution needs an M-series chip.
  • About 20 GB free disk. There are no container images on macOS, so the footprint is the binaries plus your models.
  • Outbound HTTPS to install and to download a model.
  • No password. Nothing on this path needs sudo.

Nodeau checks no macOS version number anywhere. If you are on an earlier release than we have tried, that is untested rather than unsupported, and the choice is left to you.

Step 1 — get the CLI#

Terminal
curl -fsSL https://get.nodeau.ai/install.sh | bash

Or read it first:

Terminal
curl -fsSL https://get.nodeau.ai/install.sh -o install-nodeau.sh
less install-nodeau.sh
bash install-nodeau.sh

This downloads nodeau-darwin-arm64.tar.gz, verifies its SHA-256 against the published manifest, and puts nodeau into ~/.local/bin. It refuses to run as root and calls no sudo.

The macOS archive also carries a Metal model runtime, which the script stages beside the binary so nodeau install can find it. There is nothing for you to build or supply.

Step 2 — look at the machine#

Terminal
nodeau doctor

Read-only. It reports the chip, the Metal accelerator, memory, the state directory, whether a model runtime is installed and verified, and what is running.

Step 3 — set it up#

Terminal
nodeau install --dry-run     # what would change
nodeau install               # the same, then asks

It checks four things and then acts:

CheckBlocking?
Apple Silicon — the machine reports arm64Yes
Metal accelerator — a usable GPU is presentYes
Model runtime — a prepared runtime is available, bundled or namedYes, if none can be found
Storage safety — the state directory lands on a writable, native filesystemYes

Then it creates its directories, installs the model runtime, copies the nodeau binary into Nodeau's own directory, warms the Metal shader cache so the first model run is not mistaken for a hang, and offers to add one line to your login profile.

There is no Kubernetes, no container runtime, no virtual machine and no privileged step. Everything lives in your own Library folder.

Options#

FlagWhat it does
--dry-runShow what would change and stop
--yes, -yDo not ask anything
--runtime <path>Install a prepared model runtime from a directory or .tar.gz. An explicit path always wins over the bundled one
--skip-pathDo not offer to add Nodeau to your shell PATH
--skip-binaryDo not copy the Nodeau binary into Nodeau's own directory
--state <path>Path to the install ledger
--jsonMachine-readable output. It does not imply consent — a pipeline says yes with --yes

The PATH line#

macOS has no user-writable directory on the default PATH, so one line has to go into your login profile. Nodeau shows you the exact text and asks before appending it. Declining costs nothing: the line is printed, and nodeau still works by full path.

It goes in ~/.zprofile, not ~/.zshrc. Terminal.app runs login shells, so a PATH line in .zshrc works by hand and fails in a script, an ssh command or a LaunchAgent.

It takes effect in a new terminal window.

Step 4 — run a model#

Terminal
nodeau model list          # what you can run
nodeau run <model>         # download it, admit it, serve it
nodeau ps                  # what is running

nodeau run is the supported vocabulary on both platforms. It resolves the model from the catalog, asks before downloading, runs admission, starts the model on the Mac's GPU and brings up the loopback endpoint. Then call it exactly as on Linux — see the API.

The endpoint runs as a launchd user agent in ~/Library/LaunchAgents, so it survives closing the terminal.

Unified memory#

This is the one thing about a Mac that surprises people, and it is worth understanding rather than working around.

On Apple Silicon the system, your applications and the GPU share one pool of memory. So "will this model fit" is not a fixed property of the machine — it depends on what else is open.

Nodeau reads two separate numbers:

  • a static ceiling, the most the GPU is allowed to hold. This is a property of the device and does not move, even when free memory swings by gigabytes.
  • a live figure for what is actually free right now.

Admission uses the smaller, minus a system reserve. The consequence is real and correct:

A model that started yesterday can be refused today, because you now have a browser and a video call open. Close something and try again.

That is Nodeau reading the machine honestly. Nodeau will never quietly reduce its own safety margin to make something fit — an out-of-memory kill on a machine whose display is driven by the same GPU is worse than a refusal.

If you want to accept that risk for one workload, nodeau run takes --accept-estimate-risk and --spend-safety-reserve. Both are explicit, both are per-workload, and both are recorded.

Where things live#

PathWhat
~/.local/bin/nodeauThe CLI, as the bootstrap installed it
~/Library/Application Support/Nodeau/Nodeau's own directory
~/Library/Application Support/Nodeau/state/models/Model cache
~/Library/Application Support/Nodeau/state/runtimes/The Metal model runtime
~/Library/Application Support/Nodeau/api-keyYour local API key, mode 0600
~/Library/LaunchAgents/The endpoint's user agent

XDG_CONFIG_HOME and XDG_STATE_HOME are honoured when explicitly set.

The model runtime#

On Linux a runtime is a container image with a digest, which answers for itself. A directory does not, so on macOS the runtime carries a manifest — version, engine, backend, os/arch, a SHA-256 for every file, and the upstream commit — and fails closed if it does not verify.

Installing one is verify-then-promote: a failed install leaves the previous runtime serving. nodeau doctor reports RUNTIME_MISSING, RUNTIME_CORRUPT, RUNTIME_UNVERIFIED and RUNTIME_UNMANAGED separately, because they need different answers.

Upgrading#

Terminal
curl -fsSL https://get.nodeau.ai/install.sh | bash
nodeau install

nodeau update checks first. See updating and release channels.

Uninstalling#

Terminal
nodeau uninstall --dry-run
nodeau uninstall

It removes what nodeau install put here and nothing else. A model runtime you assembled yourself, a PATH line you wrote, or a copy of nodeau you manage are all left alone, and the plan says so.

FlagWhat it does
--dry-runShow what would be removed and stop
--yes, -yDo not ask anything
--modelsAlso delete downloaded model weights
--keep-pathLeave the PATH line in your login profile
--state <path>Path to the install ledger

Your downloaded models are kept unless you pass --models. Uninstalling the software and throwing away gigabytes of downloads are different decisions.

If something went wrong#

Troubleshooting has a macOS section.

Documentation for the current published build, the beta channel. Something here wrong or missing? Tell us — a report from a machine we have never seen is the most useful thing we get.