cf CLI and cloudflare.config.ts
Vite-ready Workers that have a Worker entry use the Cloudflare
cf CLI, Vite, the official Vite plugin, and typed
cloudflare.config.ts. Wrangler stays where the platform still
delegates, including assets-only Astro until those gaps close.
Mark GO 2026-09-28 CT accepted this standard for pilots. First
MNPPI/airport-time-calc (PR #78), then MNPPI/tesseract (PR #36). Both
keep labeled transitional wrangler.jsonc. No mass fleet migrate.
BotMail (automations.uihq.com) is out of scope.
The internal ADR is docs/adr/ADR-cf-cli-migration.md in MNPPI/org-standards.
Deploy ownership stays in Cloudflare deployment.
Canonical toolchain
Section titled “Canonical toolchain”| Piece | Standard |
|---|---|
| Runtime | Node.js ≥ 22. cf refuses Node 20. |
| CLI | Project dependency cf. Global install is optional for operators. |
| Config | cloudflare.config.ts with defineConfig, bindings, and triggers from cf/config |
| Bundler | Vite + @cloudflare/vite-plugin for Worker-entry apps. Not for assets-only Astro. |
| Day-to-day | cf init / cf migrate / cf dev / cf build / cf deploy when BOS exists |
Branch environments with defineConfig(({ mode }) => …) and CLI --mode.
Do not invent Wrangler-style nested env.production blocks in the new format.
Verified on open-beta day against cf@1.0.0-beta.5. Re-check the installed
CLI before you assume a newer flag exists.
Agent discovery
Section titled “Agent discovery”Prefer:
cf cli search "migrate wrangler project"cf cli search "deploy worker"Then run <command> --help. Do not invent flags. Do not chain nested
--help. Keep search queries free of account IDs, domains, emails, and
tokens.
Launch post + installed CLI/types/codemods are source of truth until Cloudflare’s public docs index catches up.
Official migrate path
Section titled “Official migrate path”cf migrate --dry-run --bundler vitecf migrate --bundler viteUse --bundler vite only when the repo has a Worker entry. Assets-only
Astro is out of scope for that path. See pilot-proven fences.
cf migrate always creates cloudflare.config.ts. It does not overwrite an
existing target file. It returns followUps. Status may be
needs-intervention (exit 1) when blocking follow-ups remain.
Replace wrangler deploy with cf deploy only when BOS
(.cloudflare/output/v0/config.json) exists after the project build.
Keep the repository script name cf:check. Point it at cf deploy --dry-run
when BOS exists, otherwise wrangler deploy --dry-run.
No shims. Do not wrap Wrangler in a binary or script named cf.
Do not delete wrangler.jsonc or flip Workers Builds to
wrangler --experimental-new-config.
Transitional Wrangler
Section titled “Transitional Wrangler”Wrangler is allowed only when Cloudflare still delegates. Label it
transitional in AGENTS.md and on any retained wrangler.* file.
| Case | Label |
|---|---|
| JS Workers still on Wrangler/esbuild | transitional: wrangler-esbuild-delegate |
| Rust Workers | transitional: rust-wrangler |
| Python Workers | transitional: python-pywrangler |
Optional wrangler.config.ts tooling |
transitional: wrangler-tooling-config |
| Pages → Workers Assets before or beside migrate | transitional: pages-to-workers-assets |
| Assets-only Astro, no Worker entry | transitional: astro-assets-no-entry |
| No BOS after the project build | transitional: wrangler-until-bos |
Keep wrangler.jsonc (no experimental flip) |
transitional: wrangler-jsonc-retained |
cf migrate does not convert Durable Object migrations, containers,
pages_build_output_dir, site, access, keep_vars, or other unsupported
fields. Escalate those. Do not invent a workaround.
cf has no keep_vars. Move every non-secret plain var into
cloudflare.config.ts or Wrangler vars instead of depending on
keep_vars. Under transitional Wrangler, keep_vars is short-lived
migration only. Secrets survive deploy without it. See
Worker secrets and vars.
Do not invent a cf deploy keep-vars flag.
This architecture site (mnppi-architecture) stays on Wrangler until a later
pilot. That is intentional. Docs land first. It is the same assets-only Astro
shape as the first pilots.
Pilot-proven fences
Section titled “Pilot-proven fences”Recorded 2026-09-28 CT from CF Migrate → Grok on the two Mark GO pilots.
-
Assets-only Astro → Workers Static Assets.
cf migrate --bundler vitefails onassets.directorywhen there is no Worker entry. Vite is not the honest path. Keep Wrangler transitional. -
BOS required for
cf build/cf deploy. Those commands fail without.cloudflare/output/v0/config.jsonafter the project build. Without BOS, Wrangler stays the deploy andcf:checkdry-run delegate. -
Do not fleet-flip experimental new config.
wrangler --experimental-new-config(observed on 4.112.0) rejectsdefineConfig({ worker }). Do not deletewrangler.jsoncor point Workers Builds at that flag. Pilots keep labeled transitionalwrangler.jsoncbeside anycloudflare.config.tswork.
Fences
Section titled “Fences”Do not do these during a cf migrate or deploy change:
- Rewrite Proton MX on the
uihq.comapex. - Invent a public unauthenticated webhook.
- Drop or “clean up” FedRAMP D1 UUID pins.
cf migratemust not drop pins. - Force-push a protected main.
- Commit secrets. Keep them in Cloudflare or 1Password.
- Touch BotMail /
automations.uihq.com. - Change a named production-critical Worker that this standard excludes from first pilots without an explicit waiver.
Pilots and exceptions
Section titled “Pilots and exceptions”A feature this new stays on the platform adoption pilot path. Do not flip the fleet because the CLI launched.
Need a Wrangler hold past the whitelist? Use the exception process. Name the whitelist case, the owner, and the removal criterion.