Install

Install the dino CLI on macOS or Linux with one command and no Node.js, pin a version, install from CI or an AI agent safely, or use Homebrew, npm or a direct download.

One command (macOS and Linux)

curl -fsSL https://usedino.dev/install.sh | sh

No curl? Use wget:

wget -qO- https://usedino.dev/install.sh | sh

Then check it. If the installer said the folder it used isn't on your PATH, run the export line it printed first; an installer piped into sh can't change the shell you ran it from. For the standalone binary that's:

export PATH="$HOME/.local/bin:$PATH"
dino --version

This installs the standalone dino binary, so it needs no Node.js. The installer:

  • picks the build for your OS and CPU (macOS or Linux, x64 or arm64)
  • downloads it and SHA256SUMS from the GitHub release, and refuses to install if the checksum doesn't match
  • installs to ~/.local/bin without sudo, and tells you if that folder isn't on your PATH
  • never asks a question, so it's safe to run unattended

If no binary fits your machine (for example Alpine, which uses musl), it falls back to npm install -g @dino-hq/cli, which needs Node.js 22+. Read the script before running it with curl -fsSL https://usedino.dev/install.sh | less.

Pin a version

curl -fsSL https://usedino.dev/install.sh | sh -s 1.4.0
VariableWhat it does
DINO_VERSIONVersion to install (same as the argument). Default: latest
DINO_INSTALL_DIRWhere to put dino. Default: ~/.local/bin
DINO_LINUX_BASELINE1 forces the build for older Linux CPUs without AVX2, 0 never uses it. Default: detected

In CI, scripts and AI agents

Run it with pipefail and pin the version:

bash -o pipefail -c 'curl -fsSL https://usedino.dev/install.sh | sh -s 1.4.0'

Without pipefail, a pipe reports only the last command's exit code. If curl is missing, as it is in stock ubuntu and debian:*-slim images, or if the download fails, sh reads an empty script and the pipe exits 0 with nothing installed. Install curl first (apt-get update && apt-get install -y curl ca-certificates: slim images ship without package lists), or use wget, also under pipefail:

bash -o pipefail -c 'wget -qO- https://usedino.dev/install.sh | sh -s 1.4.0'

No bash? Download the script first, then run it. && stops at a failed download, so the exit code is always real:

curl -fsSLo install.sh https://usedino.dev/install.sh && sh install.sh 1.4.0

If Node.js is already there, you can skip installing entirely:

npx -y @dino-hq/cli@1.4.0 scan --endpoint https://your-api.com/graphql --format json

See For AI agents for how an agent reads the result and the exit code.

Homebrew (macOS and Linux)

brew install dino-hq/tap/dino

Installs the same standalone binary, checked against the release's SHA256SUMS, and brew upgrade dino keeps it current. No Node.js needed. The formula lives in Dino-HQ/homebrew-tap.

npm

npm install -g @dino-hq/cli    # Node.js 22+
npx @dino-hq/cli <command>     # no install

Windows

There's no PowerShell installer yet. Use npm install -g @dino-hq/cli, or download dino-windows-x64.exe from the latest release.

Download a binary directly

Every release has these files:

PlatformFile
macOS, Apple Silicondino-darwin-arm64
macOS, Inteldino-darwin-x64
Linux x64dino-linux-x64
Linux x64, CPUs without AVX2dino-linux-x64-baseline
Linux arm64dino-linux-arm64
Windows x64dino-windows-x64.exe

On macOS, use the install command rather than a browser download. The binaries aren't notarized by Apple yet, so Gatekeeper blocks a copy downloaded in a browser. The install command isn't affected.

Verify a download

Check the file against the release's SHA256SUMS:

grep ' dino-linux-x64$' SHA256SUMS | sha256sum -c -     # macOS: shasum -a 256 -c -

Each binary also has a keyless Sigstore bundle, <file>.sigstore.json, which proves it was built by Dino's release pipeline, release-sync.yml in Dino-HQ/project-dino:

cosign verify-blob ./dino-linux-x64 \
  --bundle ./dino-linux-x64.sigstore.json \
  --certificate-identity-regexp '^https://github\.com/Dino-HQ/project-dino/\.github/workflows/release-sync\.yml@refs/(tags/v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?|heads/main)$' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com'

A release is normally signed from its tag (…@refs/tags/v1.1.5). A release that was finished by a recovery run is signed from main (…@refs/heads/main, like 1.2.1), because the recovery reruns the pipeline from main against the release's tag. The pattern accepts both and nothing else. Each release's notes on GitHub give the exact identity for that release; use --certificate-identity '<identity>' with it for the strictest check.