Installation
One binary, no server required. Linux and macOS; requires Go 1.26+ and cgo
only if you build from source, and the sqlite3 CLI only for running the
test suite. Pick whichever channel fits:
Homebrew
brew tap sricola/offshoot https://github.com/sricola/offshoot
brew trust sricola/offshoot
brew install offshoot
Recent Homebrew requires the explicit brew trust step for any
third-party tap. The formula lives in-repo at
Formula/offshoot.rb.
Prebuilt binaries
Tarballs (offshoot_<tag>_<os>_<arch>.tar.gz) publish to the
releases page for each
tagged release, each with a .sha256 checksum file alongside it. For
example, for a Linux amd64 machine (substitute the tag you're
downloading):
shasum -a 256 -c offshoot_<tag>_linux_amd64.tar.gz.sha256
tar xzf offshoot_<tag>_linux_amd64.tar.gz
./offshoot version
Verify what you downloaded
Every tagged release is signed and attested by the release workflow itself — no maintainer-held key. Three independent checks, pick any:
# 1. SLSA build provenance (GitHub attestation store; needs gh >= 2.49)
gh attestation verify offshoot_v0.2.12_linux_amd64.tar.gz --repo sricola/offshoot
# 2. cosign keyless signature, pinned to this repo's release workflow identity
cosign verify-blob \
--bundle offshoot_v0.2.12_linux_amd64.tar.gz.sigstore.json \
--certificate-identity-regexp '^https://github.com/sricola/offshoot/\.github/workflows/release\.yml@refs/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
offshoot_v0.2.12_linux_amd64.tar.gz
# 3. the plain checksum, as before
shasum -a 256 -c offshoot_v0.2.12_linux_amd64.tar.gz.sha256
For a numbered release, pin the check tighter with
--certificate-identity-regexp '^https://github.com/sricola/offshoot/\.github/workflows/release\.yml@refs/tags/v'
(the plain @refs/ form above also matches a branch's workflow_dispatch
dev build), or add --signer-workflow sricola/offshoot/.github/workflows/release.yml to the gh attestation verify command above for the same tightening (gh still requires
--repo or --owner alongside it).
Each release also ships offshoot_<tag>.spdx.json, an SPDX SBOM of the Go
module graph, with a matching SBOM attestation (gh attestation verify --predicate-type https://spdx.dev/Document/v2.3 …). Releases before
v0.2.11 carry checksums only.
Docker
docker run --rm -v offshoot-data:/data ghcr.io/sricola/offshoot:latest init
Multi-architecture linux/amd64 and linux/arm64 images publish to GHCR on
every tagged release. The store lives in the /data volume, so reuse
-v offshoot-data:/data across commands
(... offshoot:latest create app, ... offshoot:latest serve, and so
on). Images are signed and attested too:
cosign verify ghcr.io/sricola/offshoot:<tag> --certificate-identity-regexp '^https://github.com/sricola/offshoot/\.github/workflows/release\.yml@refs/' --certificate-oidc-issuer https://token.actions.githubusercontent.com,
or gh attestation verify oci://ghcr.io/sricola/offshoot:<tag> --repo sricola/offshoot.
For a numbered release, tighten the regexp to
@refs/tags/v (the plain @refs/ form also matches a branch's
workflow_dispatch dev build), or add
--signer-workflow sricola/offshoot/.github/workflows/release.yml to the
gh attestation verify command alongside --repo.
go install / from source
go install github.com/sricola/offshoot/cmd/offshoot@latest
Or from a clone:
git clone https://github.com/sricola/offshoot
cd offshoot
go build -o offshoot ./cmd/offshoot
Both need Go 1.26+ with cgo enabled (offshoot embeds SQLite via
mattn/go-sqlite3).
Platform support
Linux and macOS only. Windows: use WSL2 — the Linux binaries, Docker image, and build-from-source all work there as-is. Native Windows is unsupported: offshoot leans on POSIX file semantics (unix sockets, POSIX locks) that don't map cleanly to Windows (why).
Initialize a store
Every offshoot command runs against a store — a local directory or an
S3-compatible bucket. Create one with init before anything else:
offshoot -store ./.offshoot init # local directory (the default)
offshoot -store s3://my-bucket/offshoot init # S3-compatible bucket
-store can appear anywhere in the argument list. If omitted, offshoot
uses the OFFSHOOT_STORE environment variable, and falls back to
./.offshoot if that's unset too — so after offshoot init in a project
directory, bare commands just work. Running init against an
already-initialized store fails rather than silently succeeding, so don't
script it unconditionally before every command.
The fail-closed probe: offshoot's safety rests on compare-and-swap —
every branch ref update is a conditional write. At attach time, every
command probes the store and refuses to run if conditional writes are
not enforced, rather than silently degrading. The probe re-runs on every
CLI invocation (each command attaches fresh); a long-lived daemon
(offshoot serve) pays it once per process instead of once per command.
S3 configuration
Credentials come from the AWS SDK's default chain (environment, shared
config/credentials file, IAM role) — never from an offshoot-specific
variable. Three variables are consulted for s3:// specs:
| Variable | Meaning |
|---|---|
OFFSHOOT_S3_ENDPOINT |
Custom endpoint (RustFS, MinIO, or any S3-compatible endpoint); unset means AWS's default endpoint |
OFFSHOOT_S3_REGION |
Region; defaults to auto when a custom endpoint is set |
OFFSHOOT_S3_PATH_STYLE |
1 for path-style addressing (needed for RustFS/MinIO-style local endpoints) |
For a remote (s3://) store, OFFSHOOT_CHECKOUTS controls where
checkouts are materialized locally (default: a per-store directory under
the user cache dir); local stores always keep checkouts under the store
directory itself.
Provider support
A provider is listed as supported only after the conformance suite and CAS probe pass against it for real:
| Provider | Status |
|---|---|
| AWS S3 | verified — probe + conformance + multipart passes against a real bucket (us-east-1), nightly in CI since 2026-09-25 |
| RustFS | verified in CI — the conformance suite runs against real RustFS on every PR and push to main |
| MinIO | verified through v0.2.9; no longer in CI since MinIO withdrew its community images and binaries in 2026 (same code path, nothing re-verifies it) |
| Google Cloud Storage (S3 interop) | unsupported — no conditional writes on the S3 API; the probe refuses it (why) |
See Limitations for what "S3-compatible" concretely requires.
Next
- New to offshoot? The Quickstart is the five-minute fork/rollback tour.
- Every flag of every command: the CLI reference.