• Start
Sign In

Install

Install surrealctl on macOS, Linux, or Windows, verify the download, sign in for the first time, and keep the binary up to date.

This page installs the surrealctl binary, signs you in to SurrealDB Cloud, and confirms that both worked. Pick one installation method. Everything after it applies whichever you chose.

surrealctl is a single executable with no runtime dependencies. It is published for macOS, Linux, and Windows, on both arm64 and amd64.

Note

The current release is a beta. Until the first stable release, the install script and surrealctl upgrade both follow the beta channel, and the version you get carries a -beta suffix.

On macOS and Linux, the install script detects your platform and CPU, downloads the matching asset, checks it against its published SHA-256, and only then puts it in place.

curl -fsSL https://download.surrealdb.com/surrealctl/install.sh | sh

The script is served as plain text, so you can open the same URL in a browser and read it before you run it.

It installs into the first writable directory of ~/.local/bin and /usr/local/bin, creating ~/.local/bin if neither exists. It never uses sudo. If the directory it picks is not on your PATH, the script tells you and does not edit your shell profile.

Pass options after -s --, which is how sh forwards arguments to a script it reads from a pipe.

curl -fsSL https://download.surrealdb.com/surrealctl/install.sh | sh -s -- --to ~/bin
OptionEffect
--version <VERSION>Install this exact version, written 1.0.0 or v1.0.0
--betaInstall the newest beta release
--alphaInstall the newest alpha release
--to <DIR>Install into this directory
--dry-runPrint what would be downloaded and installed, then stop
-h, --helpPrint the options and exit

Two environment variables do the same job as options, which is easier to set in a Dockerfile or a CI step.

VariableEffect
SURREALCTL_INSTALL_DIRSame as --to
SURREALCTL_DOWNLOAD_ROOTPoint the script at a different release host, for testing

Use --dry-run to see the exact URL and destination before anything is written.

Check what the script would do
curl -fsSL https://download.surrealdb.com/surrealctl/install.sh | sh -s -- --dry-run
Note

No musl build is published yet. On Alpine and other musl-based distributions the script stops and says so, rather than installing a glibc binary that cannot start. Build from source on those systems.

Download the executable, then put it somewhere on your PATH.

$version = (Invoke-WebRequest -Uri https://download.surrealdb.com/surrealctl/beta.txt -UseBasicParsing).Content.Trim()
Invoke-WebRequest -Uri "https://download.surrealdb.com/surrealctl/$version/surrealctl-$version.windows-amd64.exe" -OutFile surrealctl.exe

Read latest.txt instead of beta.txt once a stable release is published.

Every release is published under https://download.surrealdb.com/surrealctl/. Use this route for container images, air-gapped hosts, and anywhere you want the version pinned in source control.

Three text files name the current version of each channel. Each contains one line, such as v1.0.0-beta.1.

FileChannel
latest.txtStable
beta.txtBeta
alpha.txtAlpha
Download and install the current beta
version=$(curl -fsSL https://download.surrealdb.com/surrealctl/beta.txt)
curl -fsSL "https://download.surrealdb.com/surrealctl/${version}/surrealctl-${version}.darwin-arm64.tgz" \
  | tar -xz -C ~/.local/bin

Replace the asset name to match your platform.

PlatformAsset
macOS, Apple siliconsurrealctl-<version>.darwin-arm64.tgz
macOS, Intelsurrealctl-<version>.darwin-amd64.tgz
Linux, ARM64surrealctl-<version>.linux-arm64.tgz
Linux, x86-64surrealctl-<version>.linux-amd64.tgz
Windows, x86-64surrealctl-<version>.windows-amd64.exe

The archives hold a single file, surrealctl, at the root. Windows ships the executable directly, with no archive.

Every asset has a .txt file beside it holding its SHA-256, and every version directory has a SHA256SUMS covering all of them. The install script and surrealctl upgrade both check this automatically; verify by hand when you download the asset yourself.

Check one asset
version=$(curl -fsSL https://download.surrealdb.com/surrealctl/beta.txt)
asset="surrealctl-${version}.linux-amd64.tgz"
base="https://download.surrealdb.com/surrealctl/${version}"

curl -fsSLO "${base}/${asset}"
curl -fsSL "${base}/${asset}.txt"
sha256sum "${asset}"

The two digests must match. On macOS, use shasum -a 256 instead of sha256sum.

Check every asset you downloaded
curl -fsSLO "${base}/SHA256SUMS"
shasum -c --ignore-missing SHA256SUMS

Building needs a Rust toolchain. The repository pins the version it wants, so rustup fetches the right one on the first build.

git clone https://github.com/surrealdb/surrealctl
cd surrealctl
cargo install --path .

cargo install places the binary in ~/.cargo/bin, so make sure that directory is on your PATH.

surrealctl version

The command prints the version, the commit it was built from, the build date, and the target triple. If the shell reports that the command was not found, the install directory is not on your PATH.

surrealctl --help lists the command groups. Every group prints its own help, so surrealctl instance --help and surrealctl instance create --help both work.

surrealctl auth login

The default flow opens a browser, waits for you to approve the sign-in, and stores the result. Three flows are available and surrealctl picks the first one that can work here:

  1. Browser loopback — opens a browser and listens on 127.0.0.1 for the redirect. The default when a browser is available.

  2. Device code — prints a short code to type on another device. Used automatically when there is no browser, or on request with --flow device.

  3. Paste — prints a URL and takes back the address the browser was redirected to. Used with --flow paste, or when neither of the others can work.

Over SSH, surrealctl skips the browser flow without being asked, because a browser on the far end of an SSH connection opens on the wrong machine.

To force a particular flow, name it. A flow you ask for is used or it fails; surrealctl does not substitute another one silently.

surrealctl auth login --flow device
surrealctl auth login --no-browser

If the profile already has a credential, auth login reports who is signed in and does nothing. Pass --force to sign in again.

surrealctl whoami

whoami asks the API who you are, so it confirms that the stored credential is accepted and that the network path works. It is the counterpart to surrealctl auth status, which reads the local store and touches no network at all.

surrealctl auth status

For what the two credential kinds are and how to use a token in CI, see Authentication.

surrealctl status — also spelled surrealctl doctor — runs eight checks in dependency order and prints one row for each. No check can abort the command, so you get the whole diagnosis in one run.

CheckWhat it tells you
credentialWhich credential is in use, and whether it is usable. A failure here is fatal
apiWhether the API base URL answers
versionThe minimum client version the API advertises. Reported, never enforced
cloud sessionWhether a Cloud session is held. Skipped for a personal access token
organizationWhich organisation resolves, and which layer decided it
surreal binaryWhich copy the handoff commands will use
system messageAny platform notice currently published
releaseWhether a newer surrealctl release is available

Because a failure low in the table is often the one above it restated, read from the top: the first failing row is usually the cause and the rest are symptoms.

This is the one command that still prints its table when it exits non-zero, because the table is the diagnosis.

surrealctl replaces itself.

surrealctl upgrade

The command follows the channel this build is on, verifies the download against its published checksum, runs the new binary once to prove it works, and only then replaces the running one. Nothing is overwritten until every one of those steps has passed.

OptionEffect
--checkReport whether a newer release exists, and install nothing
--version <VERSION>Install this exact version instead of the newest
--channel <CHANNEL>Follow latest, beta, or alpha instead of this build's channel
--forceReplace the binary without confirming
-o, --output <PATH>Write the new binary here instead of replacing the running one
Ask without installing
surrealctl upgrade --check
Important

If the binary was installed by a package manager, upgrade refuses and names that tool's own command instead. Replacing a file a package manager owns leaves its records wrong, and the next upgrade through that tool would silently put the old version back. Use brew upgrade, cargo install --force, or your Nix workflow instead.

surrealctl status reports the release check as one of its rows. To be told automatically, at most once a day:

surrealctl config set release_check true

That prints a single line on stderr after a command finishes, and only when a terminal is attached — never in a pipe, a CI job, or --json output. Set SURREALCTL_RELEASE_CHECK to override the setting for one invocation.

surrealctl completion writes a completion script to stdout for bash, elvish, fish, powershell, or zsh.

zsh
surrealctl completion zsh > "${fpath[1]}/_surrealctl"
bash
surrealctl completion bash > /etc/bash_completion.d/surrealctl

instance sql, instance import, and instance export hand off to the surreal binary. Install it the usual way and surrealctl finds it on your PATH.

If it is missing when you run one of those three commands, surrealctl offers to fetch a copy.

`surrealctl instance sql` hands off to the `surreal` binary, and it is not installed.
? Download it from https://download.surrealdb.com now? (y/N)

The download lands in ~/.config/surrealctl/bin, never in /usr/local/bin, so it needs no sudo. The offer appears only when somebody is there to answer it: an unattended run gets an error naming the install command instead, and --yes does not turn the offer into a silent download.

surrealctl looks for the binary in this order, and the managed copy is last.

  1. The surreal_binary key in the active profile

  2. SURREALCTL_SURREAL_BINARY

  3. PATH

  4. ~/.config/surrealctl/bin/surreal

Installing surreal properly later therefore takes over with nothing to undo. To point at a specific copy, name it.

surrealctl config set surreal_binary /opt/surrealdb/bin/surreal

A path you name explicitly and that does not resolve is an error, not a fallback — silently using a different binary than the one you asked for is how the wrong version gets blamed.

Four paths, all in one directory under $XDG_CONFIG_HOME/surrealctl or ~/.config/surrealctl. XDG applies on macOS too, because this is a terminal tool that people symlink into a dotfiles repository.

FileContents
config.tomlProfiles, the remembered organisation, and other non-secrets. Safe to commit
credentials.jsonTokens, and the values that must be replaced in the same write as them. Mode 0600
credentials.lockAn empty advisory lock file, so two concurrent runs cannot corrupt a refresh
bin/surrealThe managed surreal copy, when one was downloaded

surrealctl config path prints the configuration file path. Set SURREALCTL_CONFIG_DIR to move the whole directory, or --config to point at one configuration file.

Warning

surrealctl refuses to read credentials.json if it is readable by group or other, and tells you to run chmod 600 on it. The file holds a refresh token.

Was this page helpful?