---
title: "Install the Axiom CLI"
description: "Install the axiom CLI with Homebrew or the curl install script, authenticate with axiom login, and confirm your identity and tenant with axiom whoami."
category: tutorial
surfaces: [cli]
related: [getting-started/first-node, guides/api-keys, reference/cli/axiom-login, reference/cli/axiom-whoami]
last_reviewed: 2026-06-07
---

# Install the Axiom CLI

The `axiom` CLI is how you create packages, develop nodes locally, and push
them to the Axiom platform. This page installs the CLI, logs you in, and
verifies your identity — about five minutes end to end.

## Install

Pick the method for your platform. Both drop a prebuilt `axiom` binary on your
`PATH`; you do **not** need a Go toolchain to use the CLI.

**Homebrew (macOS / Linux):**

```bash
brew install axiomide/tap/axiom
```

**Install script (macOS / Linux):**

```bash
curl -fsSL https://raw.githubusercontent.com/AxiomIDE/axiom-releases/main/install.sh | sh
```

The script detects your OS and architecture (Linux/macOS, amd64/arm64),
downloads the matching release binary, and installs it (to `/usr/local/bin`, or
`~/.local/bin` if that is not writable). Pin a version with
`AXIOM_VERSION=v1.2.3`, or change the target with `AXIOM_INSTALL_DIR`.

**Windows:** download the `.zip` for `windows/amd64` from the
[Releases page](https://github.com/AxiomIDE/axiom-releases/releases) and put
`axiom.exe` on your `PATH`. The pure-CLI commands (`init`, `validate`, `create`, `push`,
`client`, `login`) run natively on Windows; the Docker-backed commands
(`axiom build`) and the local dev server (`axiom dev`, which uses a Unix socket)
are supported **under [WSL2](https://learn.microsoft.com/windows/wsl/)**.

Released binaries ship from the public
[AxiomIDE/axiom-releases](https://github.com/AxiomIDE/axiom-releases) repo —
prebuilt binaries and the install script only; the platform source is not
published there.

Verify the binary is on your `PATH`:

```bash
axiom version
```

This prints the CLI version, for example:

```text
axiom version 0.2.0
```

Run `axiom --help` at any time to list every command, or
`axiom <command> --help` for one command's flags. The full command reference
is at [reference/cli](../reference/cli/axiom.md).

## Set up language toolchains

Authoring nodes shells out to a few per-language tools — `protoc` and language
plugins for proto codegen, plus each language's test runner. To see what you're
missing without installing anything, run:

```bash
axiom doctor
```

Bare `axiom doctor` only **checks**: it reports which toolchain pieces your
packages need and prints copy-paste install hints for the ones that are absent —
it changes nothing. Run inside a package, `axiom doctor --fix` performs the
**project-local** installs it can do safely — `go mod download`, `go install` of
the proto plugins, `npm install`, or `pip install` into an *active* virtualenv —
and only **advises** (never installs) system-level tools like `protoc`. It never
uses `sudo` or touches system packages.

(`axiom doctor` outside a package surveys every language and exits 0 — purely
informational. Inside a package it checks just that package's language and exits
non-zero when a required tool is missing, so it can gate CI.)

When you scaffold a package, `axiom init --install` runs the language's
dependency install (`pip install -r requirements.txt`, `npm install`,
`go mod download`, …) right after writing the manifests, so the generated code
compiles and tests run without a separate setup step.

You can also install the per-language tools yourself when you get to a guide;
each [Create a node](../guides/create-a-node-python.md) page lists exactly what
it needs.

## Log in with axiom login

`axiom login` authenticates you with the Axiom platform using the OAuth
Device Flow:

```bash
axiom login
```

The command prints a verification URL and a one-time user code, then opens
the URL in your default browser. Complete sign-in there via GitHub or Google
and enter the code when prompted. Meanwhile the CLI polls the platform until
you approve; on success it prints your identity:

```text
✓ Logged in as <client-id> (tenant: <tenant-id>)
```

The resulting API key is stored in `~/.axiom/credentials` (a JSON file,
written with owner-only `0600` permissions). Every authenticated CLI command
reads the key from there — you log in once per machine, not per command.

Two things to know:

- **The device code expires** (typically after 15 minutes). If you see
  `device code expired`, run `axiom login` again.
- **In CI environments**, set the `AXIOM_API_KEY` environment variable before
  running `axiom login` — the CLI saves that key directly and skips the
  browser flow entirely. You can create API keys in the account console; see
  [Create and manage API keys](../guides/api-keys.md).

## Verify with axiom whoami

`axiom whoami` shows the user and tenant associated with your stored API key:

```bash
axiom whoami
```

```text
Email:  you@example.com
Tenant: <tenant-id>
```

The tenant is the isolation boundary for everything you push: your packages,
flows, and secrets are scoped to it (see
[Sandboxing and tenancy](../concepts/sandboxing-and-tenancy.md)).

If you have not logged in yet, `axiom whoami` prints
`Not logged in. Run "axiom login" to authenticate.` and exits with a non-zero
status — run [axiom login](#log-in-with-axiom-login) first.

## Advanced: pointing the CLI at a different deployment

A released `axiom` binary already knows where to find the Axiom platform —
the deployment endpoint is baked in at build time. There is nothing to
configure: install, then run [`axiom login`](#log-in-with-axiom-login).

Two environment variables exist as an **undocumented-by-default escape
hatch** for self-hosters and platform developers who need to point the CLI
somewhere other than the baked default:

| Variable | Purpose |
|---|---|
| `AXIOM_API_URL` | Platform API base — login, push, search (include the `/api` path) |
| `AXIOM_INGRESS_URL` | Flow invocation base — include the `/invocations` path when pointing at a gateway |

```bash
# only needed for self-hosted deployments or local development
export AXIOM_API_URL="https://api.axiomide.com/api"
export AXIOM_INGRESS_URL="https://api.axiomide.com/invocations"
```

The CLI uses each value exactly as given. When you point `AXIOM_INGRESS_URL` at
an Axiom gateway, keep the `/invocations` prefix as shown above; only when you
point it straight at an ingress service (for example a local port-forward) do
you drop the prefix and use the bare origin. When you do override the endpoint,
the stored credential is just the API key — so switching `AXIOM_API_URL` to a
different deployment requires
running `axiom login` again against that deployment (the override takes
effect on the next login, not retroactively). If you're building the CLI
from source (e.g. contributing to Axiom itself), the source build has no
baked endpoint and defaults to `http://localhost:8082` / `http://localhost:8080`
for local dev clusters, so these variables matter more often in that
workflow.

## Next steps

You have a working, authenticated CLI. Continue the tutorial spine:

- [Create your first node](./first-node.md) — `axiom init`, `axiom create
  node`, `axiom dev`, `axiom test`.
- [Build your first flow](./first-flow.md) — push your package, compose a
  flow in the canvas, and `axiom publish` it to the marketplace.
- [Invoke a flow via API](./invoke-via-api.md) — call your flow with curl or
  a generated client.

For background on what you'll be building, read
[Nodes, packages, and flows](../concepts/nodes-packages-flows.md).
