Quickstart
Three commands take you from an empty AWS account to a live site: init writes the config, bootstrap creates the infrastructure, deploy builds and publishes. This page walks the whole flow, then shows how to check on the result with status and history.
Before you start you need blogwright installed in a git (or jj) repository that builds a static site with pnpm build, Node ≥ 22, and AWS credentials in the ambient provider chain. The CLI finds the repo root by walking up to the nearest .git or .jj, so every command works from any subdirectory. The binary is blogwright; bw is an alias.
1. blogwright init — write the config
Section titled “1. blogwright init — write the config”The first-run wizard asks four questions and writes a commented config/production.jsonc at the repo root:
pnpm exec blogwright initThe questions, in order:
- Site name (required) — a lowercase slug of letters, digits, and dashes. It becomes the stable part of every AWS resource name, so never change it after bootstrap.
- AWS region (required, default
us-east-1). - Custom domain (optional) — leave blank to serve from the CloudFront domain instead.
- GitHub repo for CI deploys, as
owner/repo(optional) — leave blank to skip; setting it makesbootstrapprovision a GitHub OIDC deploy role.
The result looks like this:
// config/production.jsonc — created by `blogwright init`{ "region": "us-east-1", "siteName": "example", // stable slug in every AWS resource name — never change it "domain": "example.com"}If config/production.jsonc already exists, init refuses and tells you to edit it directly. Everything beyond these keys has defaults — see the configuration reference for the full set.
2. blogwright bootstrap — create the infrastructure
Section titled “2. blogwright bootstrap — create the infrastructure”pnpm exec blogwright bootstrapBootstrap creates and reconciles the whole infrastructure graph for the environment (default production): the S3 bucket (production-<siteName>-<accountId>), the CloudFront distribution with a private origin, the builder MicroVM image, and the rest. It is safe to re-run — existing resources are left alone or reconciled.
Without a domain, the site serves straight from the distribution’s CloudFront domain, printed at the end:
Site will be served at https://d1234abcdefgh.cloudfront.netWith a domain — either "domain" in the config or the --domain flag, which overrides the config:
pnpm exec blogwright bootstrap --domain example.comblogwright requests an ACM certificate and prints the DNS records to create at your registrar:
Add these DNS records at your registrar to validate the certificate: CNAME _3f2a…example.com. -> _9d1c….acm-validations.aws.waiting for certificate to be ISSUED (Ctrl-C to background)…It then polls until the certificate is issued (Ctrl-C is safe — re-run bootstrap once DNS propagates and it picks up where it left off). Finally it prints the CloudFront domain to point your own domain at:
CloudFront domain: d1234abcdefgh.cloudfront.net point example.com (CNAME/ALIAS) at d1234abcdefgh.cloudfront.net3. blogwright deploy — build and publish
Section titled “3. blogwright deploy — build and publish”pnpm exec blogwright deployDeploy zips the repo (honoring .gitignore, named by the jj/git revision hash), uploads it, and runs a builder MicroVM that executes pnpm install && pnpm build and syncs the output to the live site/ prefix. Only files whose content actually changed are re-uploaded, and only those CloudFront paths are invalidated — an identical redeploy invalidates nothing. The run ends with a summary card:
deploy summary revision 1a2b3c4d5e6f environment production source 142 files, 812 KiB build 1m04s invalidated 12 changed paths site https://example.comOpen the site URL — you are live. Deploying covers the build lifecycle, --refresh, rollbacks, and build logs.
4. Check the result
Section titled “4. Check the result”pnpm exec blogwright status # planned graph vs. live statepnpm exec blogwright history # deployment historystatus walks every resource in the planned graph and reports whether it exists live — a drift view of the environment. history lists past deployments from their build manifests: hash, status, finish time, and duration. Both default to production; pass another environment positionally or with --env.
Next steps
Section titled “Next steps”- Deploying — the deploy lifecycle in depth: builds, invalidation, rollback, logs.
- Custom domains — certificates, DNS, and adding a domain after the fact.
- Environments — staging and other environments beyond
production. - Configuration reference — every config key and its default.