---
import BaseLayout from '../layouts/BaseLayout.astro';
import CodeBlock from '../components/CodeBlock.astro';
import DownloadSizes from '../components/DownloadSizes.astro';
import InstallMarquee from '../components/InstallMarquee.astro';
import PageHero from '../components/PageHero.astro';
import SectionIntro from '../components/SectionIntro.astro';
import { discoveryMethodTotal, discoveryServiceCount } from '../data/discovery-coverage';
const base = import.meta.env.BASE_URL;
const releaseUrl = 'https://github.com/debanjanbasu/grr-cli/releases';
const sourceExample = `git clone https://github.com/debanjanbasu/grr-cli.git
cd grr-cli
cargo build --release
./target/release/grr`;
---
<BaseLayout
title="Install grr"
description="Install grr on macOS, Linux, and Windows (x64 and ARM) with Homebrew, crates.io, or a prebuilt release archive. Release binaries are zero-config."
>
<PageHero eyebrow="install grr" title="Pick the shortest path to your shell.">
Prebuilt binaries are the easy default. If you want a package manager, a crates.io install, or a local build, the project documents each route below.
<Fragment slot="aside">One generated command tree · {discoveryMethodTotal} methods across {discoveryServiceCount} APIs</Fragment>
</PageHero>
<InstallMarquee />
<section class="install-section section" aria-labelledby="channels-title">
<div class="container">
<SectionIntro id="channels-title" eyebrow="release channels" title="Install the way you already ship software." copy="The published binary is named grr, even though the crates.io package is grr-cli because the short crate name grr is already taken." />
<div class="install-grid mt-7 grid grid-cols-1 gap-5 lg:grid-cols-2">
<article class="install-card card card-border border-base-300 bg-base-100 lg:col-span-2">
<div class="card-body gap-1 p-5">
<h2 class="card-title m-0 text-base">Prebuilt binaries</h2>
<p class="m-0 text-[13px] text-base-content/70">Download the archive for your platform from GitHub Releases. The release workflow publishes Windows x64, Windows on ARM, Linux x64, Linux ARM, and macOS ARM binaries with checksums, plus a generated winget manifest bundle — a manifest asset, not a platform build, so the sizes below list platforms only. Each build is UPX-packed when UPX succeeds and ships unpacked when it does not, so the archives stay as small as the packer allows.</p>
<DownloadSizes note="Compressed release archives for the current GitHub release. A dash means that platform is not published yet." />
<a class="btn btn-primary btn-sm mt-3 w-fit" href={releaseUrl} target="_blank" rel="noreferrer">Open GitHub Releases <span aria-hidden="true">↗</span></a>
</div>
</article>
<article class="install-card card card-border border-base-300 bg-base-100">
<div class="card-body gap-1 p-5">
<h2 class="card-title m-0 text-base">macOS + Linux</h2>
<p class="m-0 text-[13px] text-base-content/70">The repository’s Homebrew tap serves arm64 macOS and x86_64/arm64 Linux builds. Tap it, trust it, then install by formula name.</p>
<p class="install-note m-0 mt-2 text-xs text-(--quiet)">Since Homebrew 4.4, third-party taps are untrusted by default, so <code>brew trust</code> is required before Homebrew will install a formula from the tap.</p>
<CodeBlock code={'brew tap debanjanbasu/tap\nbrew trust debanjanbasu/tap\nbrew install grr'} label="homebrew" />
</div>
</article>
<article class="install-card card card-border border-base-300 bg-base-100">
<div class="card-body gap-1 p-5">
<h2 class="card-title m-0 text-base">Windows</h2>
<p class="m-0 text-[13px] text-base-content/70">winget is not published yet: every release generates the manifest bundle and attaches it to the GitHub release as <code>grr-<tag>-winget-manifests.tar.gz</code>, but the pull request to <code>microsoft/winget-pkgs</code> has not been merged (the first submission, winget-pkgs PR #441361, was rejected because the archives named the binary after its target; the archives and manifests are fixed as of v0.8.1). Until that lands, install the Windows release archive (x64 or ARM64) from GitHub Releases.</p>
</div>
</article>
<article class="install-card card card-border border-base-300 bg-base-100">
<div class="card-body gap-1 p-5">
<h2 class="card-title m-0 text-base">crates.io</h2>
<p class="m-0 text-[13px] text-base-content/70">The crate publishes as <code>grr-cli</code>; the installed executable is <code>grr</code>. The default CLI enables HTTP/3, so a crates.io source install needs nightly Rust and the <code>reqwest_unstable</code> cfg.</p>
<CodeBlock code={'RUSTFLAGS="--cfg reqwest_unstable" cargo install grr-cli'} label="cargo · unix" />
<p class="install-note m-0 mt-2 text-xs text-(--quiet)">PowerShell: set <code>$env:RUSTFLAGS='--cfg reqwest_unstable'</code> before running cargo. That is the whole feature surface: the crate has one feature, <code>cli</code> (on by default), and no per-service features — the command tree comes from the embedded Discovery index.</p>
</div>
</article>
<article class="install-card card card-border border-base-300 bg-base-100">
<div class="card-body gap-1 p-5">
<h2 class="card-title m-0 text-base">OAuth setup</h2>
<p class="m-0 text-[13px] text-base-content/70">Release binaries are zero-config: the OAuth client is compiled in at build time, so <code>grr auth login</code> works with no setup. Building from source? Run <code>grr auth setup</code> to create and store your own client, then log in.</p>
<CodeBlock code={`grr auth login\ngrr gmail users getProfile --user-id me`} label="first run" />
</div>
</article>
</div>
</div>
</section>
<section class="source-section section" aria-labelledby="source-title">
<div class="container source-grid grid grid-cols-1 items-center gap-10 lg:grid-cols-2">
<div class="source-copy reveal">
<span class="eyebrow">from source</span>
<h2 id="source-title" class="mt-1.5 mb-2 text-[clamp(22px,2.6vw,32px)] leading-[1.15]">Build the exact revision you want to run.</h2>
<p class="m-0 text-sm text-base-content/70">The repository pins Rust nightly in <code>rust-toolchain.toml</code>. A local clone uses the repository’s Cargo config, which sets the unstable reqwest cfg and the extra build-std settings needed by the CLI.</p>
<p class="m-0 mt-3 text-sm text-base-content/70">There is no stable-Rust or HTTP/2-only build: reqwest’s <code>http3</code> feature is compiled in unconditionally, so a source build needs nightly and the unstable cfg. The crate has exactly one feature, <code>cli</code> (on by default), and no per-service features — the command tree is generated from the embedded Discovery index.</p>
<a class="btn btn-outline mt-4" href="https://github.com/debanjanbasu/grr-cli#development" target="_blank" rel="noreferrer">Read development notes <span aria-hidden="true">↗</span></a>
</div>
<CodeBlock code={sourceExample} label="local clone" />
</div>
</section>
<section class="split-section section" aria-labelledby="next-title">
<div class="container prose">
<span class="eyebrow">next step</span>
<h2 id="next-title" class="mt-1.5 mb-2 text-[clamp(22px,2.6vw,32px)] leading-[1.15]">Bring your own client, only if you build.</h2>
<p>Release binaries need none of this — just run <code>grr auth login</code>. If you build from source, <code>grr auth setup</code> creates a Google Cloud project, enables the APIs, makes a Desktop OAuth client, and stores the client ID for you.</p>
<ul>
<li><a href="https://github.com/debanjanbasu/grr-cli/blob/main/docs/gcp-setup.md" target="_blank" rel="noreferrer">Google Cloud setup guide ↗</a></li>
<li><a href="https://github.com/debanjanbasu/grr-cli#60-second-quickstart" target="_blank" rel="noreferrer">60-second quickstart ↗</a></li>
<li><a href={base}>Back to the overview →</a></li>
</ul>
</div>
</section>
</BaseLayout>