Setup
One-time steps to turn this starter into a real project. Everything else is already wired.
1. Rename
package.json→namewrangler.toml→name, which becomes the Workers subdomain- the docs in
docs/(design.md,setup.md,upgrade.md,plan.md,lessons.md,development.md) — make them yours. Each carries itstitleandsummaryin frontmatter, anddocs/README.md'snavsets their order
2. Cloudflare
Deploys come from Cloudflare's Git integration (Workers Builds), not from GitHub Actions, so there's no API token or secret to keep.
In the Cloudflare dashboard, create a Worker connected to this GitHub repo. Its name must match
nameinwrangler.toml.Set its build settings. They're the same in every project, because the steps themselves live in
package.json:Build command pnpm run verify Deploy command pnpm run ship Root directory / NODE_VERSION 26
verify runs check, test and build, so a failing check stops the deploy. ship uploads what verify built. Each push to main deploys, and other branches get preview URLs.
First manual deploy, if you want one before connecting the repo:
pnpm exec wrangler login
pnpm run verify && pnpm run ship
Write pnpm run ship, never pnpm deploy: deploy is a built-in pnpm command and never reaches a script.
The Worker is reachable at <name>.<your-subdomain>.workers.dev.
3. Custom domain
wrangler.toml has a routes entry mapping the Worker to a hostname. Point it at your domain, whose zone must be on the same Cloudflare account. Cloudflare creates the DNS record and certificate on the next deploy:
"routes": [{ "pattern": "app.example.com", "custom_domain": true }]
Remove the entry to deploy to workers.dev only.
4. Branch protection + PR workflow
Requires the gh CLI, authenticated.
OWNER_REPO="your-org/your-repo"
# Require the CI check + a PR before merging to main
gh api -X PUT "repos/$OWNER_REPO/branches/main/protection" --input - <<'JSON'
{
"required_status_checks": { "strict": true, "contexts": ["ci"] },
"enforce_admins": true,
"required_pull_request_reviews": { "required_approving_review_count": 0 },
"restrictions": null,
"allow_force_pushes": false,
"allow_deletions": false
}
JSON
# Merge hygiene
gh api -X PATCH "repos/$OWNER_REPO" \
-F allow_squash_merge=true \
-F allow_merge_commit=false \
-F allow_rebase_merge=false \
-F delete_branch_on_merge=true
Raise required_approving_review_count to 1 once more than one person works on the repo.
5. Tighten the supply chain
pnpm holds back a version for a day after it's published (its default minimumReleaseAge), so a compromised release has time to be pulled. This starter keeps that default, and pnpm-workspace.yaml lets only our own packages skip it, since each reaches npm only after a 2FA approval:
minimumReleaseAgeExclude:
- "@amitkaps/*"
A fork that depends on none of them can drop the exclusion. It's the only place the cooldown is configured or documented.
That's the one-time setup. See upgrade.md (/upgrade) for keeping the fork current afterwards.