[{"data":1,"prerenderedAt":51},["ShallowReactive",2],{"\u002Fwrangler-to-cf":3},{"title":4,"description":5,"path":6,"date":7,"updated":8,"verified":8,"category":9,"keywords":10,"officialSources":16,"related":26,"readingTime":30,"html":31,"toc":32},"Migrate from Wrangler to cf","Use the official cf migrate command, inspect the generated TypeScript config, and validate the build workflow before switching your deployment.","\u002Fwrangler-to-cf","2026-09-29","2026-09-30","Migration",[11,12,13,14,15],"wrangler to cf","migrate wrangler to cf","cf migrate","cf migrate --dry-run","wrangler.jsonc to cloudflare.config.ts",[17,20,23],{"label":18,"url":19},"Official Wrangler migration guide","https:\u002F\u002Fdevelopers.cloudflare.com\u002Fcf\u002Fwrangler\u002Fmigrate\u002F",{"label":21,"url":22},"Official Wrangler to cf reference","https:\u002F\u002Fdevelopers.cloudflare.com\u002Fcf\u002Fwrangler\u002Freference\u002F",{"label":24,"url":25},"cf migration implementation","https:\u002F\u002Fgithub.com\u002Fcloudflare\u002Fcf\u002Fblob\u002Fmain\u002Fpackages\u002Fcli\u002Fsrc\u002Flib\u002Fwrangler-migration.ts",[27,28,29],"\u002Fcloudflare-config","\u002Fcf-vs-wrangler","\u002Fwrangler-to-cf-commands",3,"\u003Ch2 id=\"quick-example\">Quick example\u003C\u002Fh2>\n\u003Cdiv class=\"code-block\">\u003Cdiv class=\"code-toolbar\">\u003Cspan>Terminal\u003C\u002Fspan>\u003Cbutton type=\"button\" data-copy-code aria-label=\"Copy code\">Copy\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre>\u003Ccode class=\"hljs language-bash\">\u003Cspan class=\"hljs-comment\"># Node.js 22.18 or newer\u003C\u002Fspan>\nnpm i -g cf\n\n\u003Cspan class=\"hljs-comment\"># Run inside your existing project\u003C\u002Fspan>\ncf migrate --dry-run\n\n\u003Cspan class=\"hljs-comment\"># Apply the migration after reviewing the plan\u003C\u002Fspan>\ncf migrate\n\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cp>\u003Ccode>cf migrate\u003C\u002Fcode> is Cloudflare’s migration tool. This guide helps you review its output; it does not implement a replacement converter.\u003C\u002Fp>\n\u003Ch2 id=\"start-with-a-clean-working-tree\">Start with a clean working tree\u003C\u002Fh2>\n\u003Cp>Commit or otherwise preserve your existing changes first. The command includes a Git worktree check. \u003Ccode>--force\u003C\u002Fcode> bypasses that protection, so use it only when you have intentionally accounted for your local changes.\u003C\u002Fp>\n\u003Cp>Before migrating, install the project’s dependencies and check its local Wrangler version. Projects that continue building through Wrangler need version 4.136.0 or later for \u003Ccode>cf dev\u003C\u002Fcode>, \u003Ccode>cf build\u003C\u002Fcode> and \u003Ccode>cf deploy\u003C\u002Fcode>. Do not run those project commands against an unmigrated Wrangler project: automatic configuration does not read its Wrangler file.\u003C\u002Fp>\n\u003Cdiv class=\"code-block\">\u003Cdiv class=\"code-toolbar\">\u003Cspan>Terminal\u003C\u002Fspan>\u003Cbutton type=\"button\" data-copy-code aria-label=\"Copy code\">Copy\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre>\u003Ccode class=\"hljs language-bash\">\u003Cspan class=\"hljs-comment\"># Inspect existing changes\u003C\u002Fspan>\ngit status --short\n\n\u003Cspan class=\"hljs-comment\"># Select a file explicitly when necessary\u003C\u002Fspan>\ncf migrate wrangler.jsonc --dry-run\n\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cp>The migration accepts Wrangler configuration files, including TOML, JSON and JSONC. Run it from the project that owns the configuration so dependency and script edits target the intended package.\u003C\u002Fp>\n\u003Ch2 id=\"choose-the-build-integration\">Choose the build integration\u003C\u002Fh2>\n\u003Cp>The CLI selects Vite when \u003Ccode>@cloudflare\u002Fvite-plugin\u003C\u002Fcode> is declared; otherwise it defaults to the Wrangler bundler. You can explicitly select the path your project needs.\u003C\u002Fp>\n\u003Cdiv class=\"code-block\">\u003Cdiv class=\"code-toolbar\">\u003Cspan>Terminal\u003C\u002Fspan>\u003Cbutton type=\"button\" data-copy-code aria-label=\"Copy code\">Copy\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre>\u003Ccode class=\"hljs language-bash\">cf migrate --bundler vite --dry-run\ncf migrate --bundler wrangler --dry-run\n\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cp>Vite being present for tests does not automatically mean Vite owns your production build. Review package scripts and plugin integration together. The choice of bundler and the CLI’s later framework detection are separate things to verify.\u003C\u002Fp>\n\u003Cp>Read the dry-run follow-up list before applying changes. An exit status of \u003Ccode>1\u003C\u002Fcode> with \u003Ccode>[required]\u003C\u002Fcode> items means the migration needs manual work; it does not by itself mean the conversion failed.\u003C\u002Fp>\n\u003Ch2 id=\"review-the-result\">Review the result\u003C\u002Fh2>\n\u003Cp>After migration, review the full diff rather than only checking that \u003Ccode>cloudflare.config.ts\u003C\u002Fcode> exists:\u003C\u002Fp>\n\u003Col>\n\u003Cli>Compare the Worker name, compatibility date, entrypoint, bindings and resource identifiers with the original deployment.\u003C\u002Fli>\n\u003Cli>Check the selected bundler and build settings. Vite settings may need to be moved by hand; Wrangler builds use the generated \u003Ccode>wrangler.config.ts\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>Resolve each \u003Ccode>[required]\u003C\u002Fcode> item and \u003Ccode>TODO(@cloudflare)\u003C\u002Fcode> in \u003Ccode>cloudflare.config.ts\u003C\u002Fcode>, then remove its migration-incomplete \u003Ccode>throw\u003C\u002Fcode> statement.\u003C\u002Fli>\n\u003Cli>Review each Wrangler environment as a cf mode. The default mode differs between Vite and Wrangler builds; pass \u003Ccode>--mode\u003C\u002Fcode> explicitly when the target matters.\u003C\u002Fli>\n\u003Cli>Update package scripts and type generation yourself. \u003Ccode>cf migrate\u003C\u002Fcode> leaves scripts, \u003Ccode>vite.config.ts\u003C\u002Fcode>, \u003Ccode>.gitignore\u003C\u002Fcode>, \u003Ccode>tsconfig.json\u003C\u002Fcode> and source files unchanged.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>By default the command installs cf as a project dependency. \u003Ccode>--no-install\u003C\u002Fcode> skips dependency installation, but you must install it before running the project. Add \u003Ccode>.cloudflare\u002F\u003C\u002Fcode> to \u003Ccode>.gitignore\u003C\u002Fcode>; include generated \u003Ccode>.cloudflare\u002Ftypes\u003C\u002Fcode> in TypeScript after \u003Ccode>cf workers types\u003C\u002Fcode> or your Vite build writes them.\u003C\u002Fp>\n\u003Ch2 id=\"validate-before-switching-ci\">Validate before switching CI\u003C\u002Fh2>\n\u003Cdiv class=\"code-block\">\u003Cdiv class=\"code-toolbar\">\u003Cspan>Terminal\u003C\u002Fspan>\u003Cbutton type=\"button\" data-copy-code aria-label=\"Copy code\">Copy\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre>\u003Ccode class=\"hljs language-bash\">cf dev\ncf build\ncf deploy --dry-run\n\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cp>Test the same application behavior you tested with Wrangler: requests, local data access and any stateful classes. \u003Ccode>cf deploy --dry-run\u003C\u002Fcode> builds and validates without API requests, though a project missing \u003Ccode>cloudflare.config.ts\u003C\u002Fcode> can still be configured locally first. Review the \u003Ca href=\"\u002Fcf-deploy\">deploy workflow\u003C\u002Fa> before trying a deployment.\u003C\u002Fp>\n\u003Cp>A successful migration is a source transformation, not evidence that production resources, secrets or databases have moved. Use the \u003Ca href=\"\u002Fcloudflare-config\">binding examples\u003C\u002Fa> to inspect resource references. Preserve an easy rollback to the original scripts until the new workflow is validated.\u003C\u002Fp>\n\u003Ch2 id=\"common-mistakes\">Common mistakes\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>Running migration with unrelated uncommitted edits and losing track of which changes belong to the migration.\u003C\u002Fli>\n\u003Cli>Treating a generated config as proof that a framework supports all cf build flags.\u003C\u002Fli>\n\u003Cli>Assuming a renamed binding also renames the deployed resource.\u003C\u002Fli>\n\u003Cli>Updating the CI command before testing the new build output locally.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>See \u003Ca href=\"\u002Fcf-vs-wrangler\">cf vs Wrangler\u003C\u002Fa> for the transition context and \u003Ca href=\"\u002Fwrangler-to-cf-commands\">command reference\u003C\u002Fa> for workflows that have changed shape.\u003C\u002Fp>\n",[33,36,39,42,45,48],{"id":34,"text":35},"quick-example","Quick example",{"id":37,"text":38},"start-with-a-clean-working-tree","Start with a clean working tree",{"id":40,"text":41},"choose-the-build-integration","Choose the build integration",{"id":43,"text":44},"review-the-result","Review the result",{"id":46,"text":47},"validate-before-switching-ci","Validate before switching CI",{"id":49,"text":50},"common-mistakes","Common mistakes",1790729614467]