Ngày 28/09/2026, Cloudflare mở beta cho cf, một CLI phủ toàn bộ Cloudflare API và dùng cấu hình bằng TypeScript. Đây là công cụ được định hướng sẽ thay thế Wrangler trong dài hạn. Bài viết này giới thiệu lý do cf ra đời, những thay đổi chính, sau đó đi qua các bước thực hành từ cài đặt đến CI. Vì cf còn ở giai đoạn beta, một số chi tiết có thể thay đổi, và mình sẽ ghi rõ những điểm chưa xác minh được.

Vì sao có cf

Theo Cloudflare, mức độ dùng Wrangler bởi agent tăng rất nhanh. Tháng 3/2026, agent chiếm một phần tư lượt dùng Wrangler, và tuần trước khi cf ra mắt con số này đạt 48%. Vấn đề là Wrangler chỉ có khoảng 280 lệnh, trong khi API của Cloudflare có hàng nghìn thao tác. Thuật ngữ giữa các lệnh cũng không thống nhất, ví dụ d1 info, hyperdrive get và workflows describe do mỗi nhóm sản phẩm tự đặt.

Giải pháp là Forge, pipeline sinh SDK nội bộ mà Cloudflare đang mở mã nguồn. Mọi API của Cloudflare đều có OpenAPI schema, và chỉ cần chú thích thêm một chút là Forge sinh được lệnh CLI. Nhờ vậy cf mở rộng từ khoảng 280 lệnh lên hơn 3000 thao tác, với cú pháp nhất quán.

Bốn thay đổi chính

Phủ toàn bộ API. Bề mặt lệnh sinh tự động từ OpenAPI, bên ngoài là lớp yargs mỏng cùng một số workflow viết tay. Cấu trúc chung của lệnh sinh tự động là cf, tên product, nhóm con nếu có, rồi thao tác.

JSON là đầu ra mặc định. Wrangler chỉ hỗ trợ cờ json ở một số lệnh, còn nhiều lệnh in bảng unicode dành cho người đọc. cf đổi sang JSON mặc định, in đẹp cho người và nén gọn cho agent để tiết kiệm ngữ cảnh.

Cấu hình bằng TypeScript. Tệp cloudflare.config.ts thay cho TOML và JSONC. Language server kiểm tra kiểu ngay trong editor, và bạn có thể viết cấu hình theo kiểu lập trình thay vì sao chép các khối env.

Vite làm nền tảng. cf dùng Vite thay cho esbuild, đi kèm dev server có hot module replacement và Cloudflare Vite Plugin. Những Worker cần esbuild, cùng Worker Rust và Python, vẫn được cf ủy quyền cho Wrangler khi chạy dev và deploy.

Cài đặt và xác thực

cf yêu cầu Node.js 22 trở lên. Cài global và đăng nhập:

node --version
npm i -g cf
cf auth login

Bật shell completion cho bash:

cf complete bash >> ~/.bashrc

Trong CI hoặc script không tương tác, cf đọc hai biến môi trường CLOUDFLARE_API_TOKEN và CLOUDFLARE_ACCOUNT_ID. Một báo cáo thử nghiệm với bản 1.0.0 beta 5 cho biết các secret CI đang dùng cho Wrangler mang sang được nguyên trạng. Hãy tạo token với quyền tối thiểu cho những tài nguyên bạn thao tác.

Worker đầu tiên

Tạo dự án trong một thư mục trống:

mkdir my_worker && cd my_worker
cf init

Lệnh này sinh cloudflare.config.ts, vite.config.ts, src/index.ts, tsconfig.json, package.json và .gitignore, cài dependency bằng package manager bạn chọn, rồi sinh type cho Worker tại .cloudflare/types/index.d.ts. Nếu bạn bỏ qua bước cài dependency, type sẽ được sinh sau bởi cf dev hoặc script typecheck của dự án. Lệnh cf init workers là initializer mặc định và hiện làm đúng việc tương tự.

Chạy local và triển khai:

cf dev
cf deploy

Với dự án có sẵn, cf init và cf deploy có thể tự cấu hình cho Cloudflare, gồm cài Cloudflare Vite Plugin và tạo tệp cấu hình. Site tĩnh không cần tệp cấu hình, chỉ cần chạy cf deploy trong thư mục dự án.

cloudflare.config.ts

Cấu hình tối thiểu, theo ví dụ trong bài ra mắt:

import { defineConfig } from "cf/config";
import * as entrypoint from "./index.js" with { type: "cf-worker" };
 
export default defineConfig({
  worker: {
    name: "example_worker",
    entrypoint,
    compatibilityDate: "2026-09-27",
  },
});

Trường compatibilityDate giữ vai trò như ở Wrangler, cố định hành vi runtime theo một mốc ngày. Hãy đặt nó bằng ngày bạn bắt đầu dự án. Cloudflare cho biết đây mới là bước đầu, và hướng tới việc quản lý cả policy, zone, DNS qua cùng một tệp cấu hình.

Khai báo binding

Mọi tài nguyên được khai báo trong trường env thông qua helper bindings, và editor sẽ gợi ý cùng giải thích từng loại:

import { bindings, defineConfig } from "cf/config";
 
export default defineConfig({
  worker: {
    // các trường name, entrypoint, compatibilityDate như trên
    env: {
      API_URL: bindings.text("https://example.com"),
      API_TOKEN: bindings.secret(),
      CACHE: bindings.kv({ id: "your_namespace_id" }),
      DATABASE: bindings.d1({ name: "example_database" }),
      UPLOADS: bindings.r2({ name: "example_uploads" }),
      JOBS: bindings.queue<{ userId: string }>({ name: "example_jobs" }),
      AI: bindings.ai(),
      SEARCH_INDEX: bindings.vectorize({ name: "example_search" }),
      API: bindings.worker({ worker: "example_api" }),
    },
  },
});

Biến văn bản dùng bindings.text, giá trị bí mật dùng bindings.secret, còn kv, d1, r2 và vectorize có helper tương ứng. Hàng đợi dùng bindings.queue với kiểu của message truyền qua generic, và gọi Worker khác dùng bindings.worker. Mình chưa tìm thấy tài liệu chính thức về cách nhập giá trị cho secret sau khi khai báo, nên bạn hãy tra bằng cf cli search ở phần dưới.

Trigger

Route, cron, queue và email nằm chung trong một khối triggers:

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]"] }),
    ],
  },
});

Nhìn vào khối này, bạn thấy ngay mọi sự kiện có thể làm Worker chạy. Repo còn có workflow riêng để phát hành trigger là cf workers triggers deploy.

Nhiều môi trường

Thay vì lặp lại khối env cho từng môi trường, bạn viết một hàm nhận tham số mode của Vite và rẽ nhánh theo đó:

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",
      ),
      DATABASE: bindings.d1({ name: `example_${mode}_database` }),
      UPLOADS: bindings.r2({ name: `example_${mode}_uploads` }),
    },
  },
}));

Cloudflare cho biết một số cấu hình Wrangler nội bộ dài hơn 5000 dòng đã giảm khoảng 40% nhờ cách làm này. Tên cờ để chọn mode khi build hoặc deploy mình chưa xác minh được, bạn hãy xem phần help của cf build và cf deploy.

Tìm lệnh bằng ngôn ngữ tự nhiên

Với hơn 3000 thao tác, không ai nhớ hết lệnh. Lệnh cf cli search cho phép mô tả việc cần làm, và một chỉ mục tìm kiếm nhỏ trả về các thao tác phù hợp dựa trên mô tả API và tham số:

cf cli search "purge cache for a zone"

Khi đã chọn được thao tác, xem tham số bằng phần help của chính lệnh đó:

cf <product> <operation> --help

Một tài liệu bên thứ ba còn ghi nhận cf có lệnh cf schema để xem cấu trúc request và cờ dry run để xem trước thao tác. Vì chưa thấy trong tài liệu chính thức, hãy kiểm tra trên phiên bản bạn cài trước khi đưa vào quy trình.

Xử lý JSON với jq

Vì JSON là mặc định, bạn lọc trực tiếp bằng jq mà không cần cờ riêng:

cf <product> list | jq '.'

Hãy thay dấu chấm bằng biểu thức phù hợp với cấu trúc thật của từng lệnh. Lưu ý các lệnh list không tự phân trang, nên với danh sách lớn bạn cần tự lặp theo trang. Với những thao tác cần nhiều thông tin, chẳng hạn mua tên miền, cf hiển thị biểu mẫu với các trường được kiểm tra thay vì bắt bạn nối một chuỗi tham số dài.

Chuyển từ Wrangler sang cf

Chạy trong thư mục gốc của dự án:

cf migrate

Worker đã build bằng Vite được chuyển thành cloudflare.config.ts. Worker dựa vào esbuild của Wrangler thì cf tiếp tục ủy quyền việc build cho Wrangler. Từ các báo cáo thử nghiệm thực tế, có vài điểm nên biết:

  • Nếu dự án chưa khai báo @cloudflare/vite-plugin, migrate chọn bundler kiểu Wrangler, về bản chất vẫn là Wrangler bên dưới. Bạn cần truyền bundler là vite để chuyển hẳn.
  • Một số binding như Workflows có thể bị để lại dạng TODO, dù thư viện cấu hình đã có helper tương ứng. Hãy đọc kỹ tệp sinh ra và xử lý bằng tay.
  • Nên chạy trên nhánh riêng, đọc diff, chạy cf dev để kiểm tra rồi mới deploy.

Về lộ trình, khi beta kết thúc Cloudflare sẽ phát hành bản major cuối của Wrangler để chuyển hướng người dùng sang cf, và vẫn bảo trì Wrangler thêm 18 tháng. Bạn có đủ thời gian để chuyển dần.

Đưa cf vào CI

Cài cf như devDependency để cả nhóm dùng chung một phiên bản, sau đó pipeline gồm:

npm ci
npm test
npx cf deploy

Đặt CLOUDFLARE_API_TOKEN và CLOUDFLARE_ACCOUNT_ID trong secret của nền tảng CI. Vì cf còn beta, hãy ghim phiên bản cụ thể thay vì dùng latest. Repo hiện phát hành prerelease theo từng pull request và từng commit trên nhánh chính, nên hành vi có thể đổi giữa các bản.

Dùng cf cùng coding agent

Đây là mục tiêu thiết kế chính của cf. Vài nguyên tắc thực tế:

  • Yêu cầu agent bắt đầu bằng cf cli search khi chưa biết lệnh, thay vì đoán cú pháp.
  • Tận dụng cấu hình TypeScript để language server trong các công cụ như Claude Code hoặc Codex đọc được kiểu của binding và trigger, cho gợi ý chính xác hơn.
  • Thêm hướng dẫn về cf vào AGENTS.md của dự án. Cloudflare nhận định việc này ít gây nhầm lẫn hơn so với để agent phân biệt hai phiên bản của Wrangler.
  • Giới hạn quyền của API token mà agent dùng. cf phủ toàn bộ API, nên một token quá rộng sẽ mở ra rất nhiều thao tác.

Hạn chế hiện tại

Tài liệu trong repo nêu ba khác biệt so với Wrangler. cf chưa có lệnh tail cho Worker, nên chưa thay được wrangler tail để stream log. Thông tin account_id lấy từ thiết lập tài khoản trong cloudflare.config.ts thay vì wrangler.toml. Các lệnh list không tự phân trang. Ngoài ra, những Worker cần esbuild, Rust hoặc Python vẫn phụ thuộc Wrangler cho dev và deploy.

Nên dùng khi nào

Hãy dùng cf khi bạn cần tự động hóa các thao tác API rộng hơn những gì Wrangler cung cấp, khi làm việc với coding agent, hoặc khi muốn cấu hình có kiểm tra kiểu và ít lặp. Giữ Wrangler cho dự án production cần xem log theo thời gian thực, hoặc Worker chưa build được bằng Vite. Hai công cụ chạy song song được trong giai đoạn chuyển tiếp.

Kết luận

cf cho thấy hướng đi của Cloudflare: CLI sinh từ OpenAPI, đầu ra JSON, cấu hình bằng TypeScript và khả năng tìm lệnh bằng ngôn ngữ tự nhiên. Điểm khởi đầu hợp lý là cài cf, tạo một Worker nhỏ bằng cf init, thử vài binding, rồi chạy cf migrate trên một nhánh riêng của dự án hiện có. Vì đang beta, hãy đối chiếu với bài ra mắt tại blog.cloudflare.com/cloudflare-cf-cli-launch và repo github.com/cloudflare/cf trước khi áp dụng rộng.