Agent-driven Wrangler usage has climbed steadily: a quarter of all Wrangler use in March 2026, up from single digits a year earlier, and 48% last week. Agents also behave differently from humans at the terminal — they run almost twice as many distinct commands per day and are nearly four times as likely to issue six or more commands. That demand collides with a hard ceiling: Wrangler exposes roughly 280 operations, while Cloudflare offers thousands.

cf is a new CLI intended to close that gap. Its design assumptions are agent-first: bespoke search and steering for command discovery, JSON as the default output format (pretty printed for humans, condensed for agents), cloudflare.config.ts as a TypeScript configuration format for all of Cloudflare starting with Workers, and Vite as the default toolchain.

npm i -g cf

From ~280 commands to the full API surface

Wrangler grew command by command, with each product team contributing its own conventions. That produced inconsistent terminology across d1 info, hyperdrive get, and workflows describe, divergent approaches to identical problems, and large custom command experiences that saw very little use. Standardizing after the fact across ~280 command paths was impractical.

The expansion instead comes from Forge, Cloudflare's unified API generation pipeline, which generates CLI commands directly from the same OpenAPI schemas that back the API documentation and SDK generation. A small amount of extra annotation on those schemas is enough to drive command generation, taking cf from ~280 Wrangler functions to more than 3,000 API operations. A single tool can then set up a Worker, deploy it, observe it, protect it with Cloudflare Access, buy a domain, and put it behind Cloudflare WAF.

Designing for an agent with no prior context

Wrangler benefitted from years of documentation, blog posts, and third-party guides absorbed into LLM training — and suffers from the same fact, since learned behavior resists change. Shipping a brand-new CLI avoids that conflict: context injections and appended AGENTS.md files make an unfamiliar tool less confusing to an agent than reconciling two versions of one it already knows. cf launches with several agent-focused features and more are planned.

JSON by default, with a form for humans

Agents using Wrangler append --json to every command and pipe results through jq, but only some Wrangler commands supported the flag; others emitted unicode tables built for human eyes. Parsing those costs tokens and time. cf inverts the default so agents get JSON without asking, which is the right tradeoff for the many commands humans will rarely touch directly. For operations that genuinely need personal input — buying a domain, for example — cf deconstructs the API's requirements into a sequence of validated inputs that can be filled in as a form rather than chained as a long series of named parameters.

Command discovery without context bloat

Three thousand possible routes is too many to enumerate in a prompt, so cf cli search accepts a natural-language description and returns matching commands from a small search index built on API descriptions and parameters. Agents are told about the command automatically the first time they run --help.

A configuration format that type-checks

cloudflare.config.ts is TypeScript-based, which makes it programmatic for humans and parseable for agents. Typed configuration lets agents identify and edit the file without prior knowledge of the format, including elements like env that differ substantially from Wrangler's feature of the same name. Agents with LSP plugins — Claude Code and Codex among them — can interpret the format in context and produce more accurate suggestions. TOML offered no accessible schema, and JSONC's linked schema went largely unused.

Cloudflare's own Wrangler configuration has been condensed by 40%, from over 5,000 lines of per-developer environments to factory files that build each developer's configuration. The mechanism is defining every environment from one universal base and switching on Vite's native mode argument, instead of copying env blocks.

import { bindings, defineConfig } from "cf/config";
import * as entrypoint from "./index.js" with { type: "cf-worker" };

export default defineConfig(({ mode }) => ({
  worker: {
    name: "example-worker", 
      entrypoint,
      compatibilityDate: "2026-09-27",
      env: {
        Environment: bindings.text(`This is ${mode} environment`),
      },
    },
}));

cf migrate moves an existing Worker to the new format. Helper functions cover common needs: bindings is a single place to discover environment variables, storage, databases, and queues with editor autocompletion and explanation, while a triggers helper collects routes, queues, schedules, and email triggers — the actions that can cause a Worker to run — into one block instead of scattering them.

import { bindings, defineConfig } from "cf/config";

export default defineConfig(({ mode }) => ({
  worker: {
    // ...
    env: {
      API_URL: bindings.text(
        mode === "production"
          ? "https://example.com"
          : "https://staging.example.com",
      ),
      API_TOKEN: bindings.secret(),
      CACHE: bindings.kv({
        id: mode === "production"
          ? "production-namespace-id"
          : "staging-namespace-id",
      }),
      DATABASE: bindings.d1({ name: `example-${mode}-database` }),
      UPLOADS: bindings.r2({ name: `example-${mode}-uploads` }),
      JOBS: bindings.queue < { userId: string } > ({
        name: `example-${mode}-jobs`,
      }),
      AI: bindings.ai(),
      SEARCH_INDEX: bindings.vectorize({
        name: `example-${mode}-search`,
      }),
      API: bindings.worker({ worker: `example-${mode}-api` }),
    },
  },
}));
import { defineConfig, triggers } from "cf/config";

export default defineConfig({
  worker: {
    // ...
    triggers: [
      triggers.fetch({ pattern: "example.com/*" }),
      triggers.scheduled({ schedule: "0 * * * *" }),
      triggers.queue({ name: "jobs", maxBatchSize: 10 }),
      triggers.email({ addresses: ["[email protected]"] }),
    ],
  },
});

defineConfig.worker is the starting point, but the intent is for cloudflare.config.ts to manage Cloudflare as a whole. Products and their APIs will be expressible through type-safe configuration, extending to policies, zones, and DNS.

Vite as the default toolchain

Wrangler predates Vite and bundled Workers with esbuild; its dev server on port 8787 was homegrown, so changes meant working inside Cloudflare-specific internals like Miniflare. Vite brings hot module replacement, tree-shaking builds via the Rust-based Rolldown, and a large plugin ecosystem. The Cloudflare Vite Plugin supports anything Vite supports and is the recommended way to build Workers, whether the project is frontend-focused or a backend API; paired with the Vitest plugin it matches the Workers runtime while exposing bindings and platform APIs directly.

cf defaults to Vite. Many Workers will migrate with agent assistance, but because some need esbuild, Rust, or Python, cf continues to delegate dev and deployment to Wrangler in those cases.

Migration path and Wrangler's timeline

cf migrate

Workers already building with Vite are converted to cloudflare.config.ts automatically; Workers that depend on Wrangler for esbuild keep delegating their builds. When the open beta ends, Cloudflare will ship a final major version of Wrangler that points users and agents to cf, and will maintain Wrangler for 18 months after that.

New projects can be configured for Cloudflare with cf init/deploy, which installs the Cloudflare Vite Plugin and creates a configuration file, or with cf init for a Hello World project. Static sites still need no configuration file — cf deploy in the project directory is enough.

cf is open source, with issues reported to the GitHub repository.