heron

Pro · Documentation

heron docs

Everything to go from brew install to a diff-only deploy in CI. v0.9.1 · MIT · Go.

Install

A single static binary, ~6 MB. Pick whichever you already use.

Homebrew

brew install heron-cli/heron/heron

go install

go install github.com/heron-cli/heron@latest

curl | sh

curl -fsSL https://get.heron.dev | sh

Verify the install:

heron --version
# v0.9.1

Quick start

Point heron at a build directory and a bucket. The first deploy uploads everything; every deploy after that uploads only what changed.

npm run build

# Diff-only upload of ./dist to your bucket
heron deploy ./dist --bucket my-site --profile prod

Made a mistake? Roll back to the previous manifest in one command — no re-upload:

heron rollback --bucket my-site --profile prod

Command reference

heron deploy

Hash the build directory, diff against the remote manifest, and upload only what changed.

heron deploy ./dist --bucket my-site --profile prod
--bucket <name>
Target S3-compatible bucket. Required unless set in heron.toml.
--profile <name>
Named profile from heron.toml (credentials, endpoint, prefix).
--dry-run
Print the upload plan and byte count without writing anything.
--concurrency <n>
Parallel multipart uploads. Defaults to 8.

heron rollback

Point the live manifest at a previous deploy. Instant, atomic, and reversible.

heron rollback --to 0f3c9a1 --bucket my-site --profile prod
--to <manifest>
Manifest hash to switch to. Omit to roll back one deploy.
--list
Show the last 20 manifests with timestamps and sizes.

heron status

Compare local build output against the live manifest without uploading.

heron status ./dist --bucket my-site --profile prod
--json
Machine-readable output for CI gates and scripts.

heron manifest

Inspect, export, or prune the remote manifest history.

heron manifest prune --keep 30 --bucket my-site
prune --keep <n>
Delete all but the most recent <n> manifests and their orphaned objects.
export <file>
Write the current manifest to a local JSON file.

Configuration

Commit a heron.toml with named profiles. Credentials never go in the file — heron reads them from the environment or your cloud's default chain.

# heron.toml — committed to your repo, no secrets inside.
# Credentials come from the environment or your cloud's default chain.

[profile.prod]
endpoint   = "https://s3.amazonaws.com"
bucket     = "my-site"
prefix     = "static/"
region     = "us-east-1"
concurrency = 12

[profile.preview]
endpoint = "https://<account>.r2.cloudflarestorage.com"
bucket   = "my-site-preview"
prefix   = "pr/"

CI usage

heron is built for cold CI runners — it reads the remote manifest, so a fresh runner still uploads only the diff.

# .github/workflows/deploy.yml
- name: Deploy static assets
  run: |
    npm run build
    heron deploy ./dist --profile prod
  env:
    AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
    AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

This page is the Pro edition's in-house docs. The canonical reference lives in the README on GitHub.

Star heron on GitHub