Deployment
Checked first, never forced.

Every deploy runs vage check and vage build first, shows you its plan, and asks before it changes anything. Use --dry-run to see the plan, and --yes once you've reviewed it. A deploy only reports success when the live site answers.

Cloudflare Workers (recommended on Cloudflare)

Cloudflare now hosts new static sites as Workers. Set the target once:

TypeScript
// vage.config.ts
deploy: { target: "cloudflare-workers", cloudflareWorker: "my-site" },
terminal
npx vage deploy

vagejs uploads a new version and switches all traffic to it, so a custom domain never goes offline during a deploy. Your 404 page, redirects (as real 301s) and security headers all work.

Custom domains: add a wrangler.jsonc with your routes. vagejs uses it, shows its Worker name in the plan, and refuses to deploy if the file points at a different Worker or folder than expected:

{
  "name": "my-site",
  "compatibility_date": "2026-10-01",
  "routes": [{ "pattern": "example.com", "custom_domain": true }],
  "assets": { "directory": "dist", "not_found_handling": "404-page" }
}

Sign in with npx wrangler login, or set CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID.

GitHub Pages

terminal
npx vage deploy:github --remote https://github.com/you/site.git   # first push
npx vage deploy                                                  # target: github-pages (the default)

deploy:github refuses to commit secret-looking files, dist/ or node_modules/, and never force-pushes. deploy adds a GitHub Actions workflow that checks, builds and publishes, then waits for GitHub to confirm. GitHub Pages needs a custom domain or a <user>.github.io repository.

Cloudflare Pages

terminal
npx vage deploy --target cloudflare-pages --project my-site

For existing Pages projects. Branches other than production get their own preview address. For new sites, use Workers.

After you deploy

terminal
npx vage verify                          # the live site matches your files
npx vage indexnow --changed-since HEAD~1 # tell IndexNow search engines what changed

verify catches anything on the live site that isn't in your project, such as injected links, scripts or pages. IndexNow needs a key in integrations.indexNow and is a hint, not a guarantee of crawling.

Start with one command.
You'll have a site running in a minute.

npm create vagejs@latest my-site

Read the docsUse it with your AI assistant