[{"data":1,"prerenderedAt":53},["ShallowReactive",2],{"\u002Fcloudflare-config":3},{"title":4,"description":5,"path":6,"date":7,"updated":8,"verified":7,"category":9,"keywords":10,"officialSources":16,"related":26,"readingTime":32,"html":33,"toc":34},"cloudflare.config.ts: a practical guide","Define a Worker and its bindings with typed helpers. Start with the smallest configuration, then add only the resources your application uses.","\u002Fcloudflare-config","2026-09-29","2026-09-30","Configuration",[11,12,13,14,15],"cloudflare.config.ts","cloudflare config typescript","cloudflare config example","cloudflare.config.ts worker.env","cf\u002Fconfig defineConfig",[17,20,23],{"label":18,"url":19},"Cloudflare configuration types and helpers","https:\u002F\u002Fgithub.com\u002Fcloudflare\u002Fworkers-sdk\u002Ftree\u002Fmain\u002Fpackages\u002Fconfig\u002Fsrc",{"label":21,"url":22},"cf CLI source and README","https:\u002F\u002Fgithub.com\u002Fcloudflare\u002Fcf\u002Ftree\u002Fmain\u002Fpackages\u002Fcli",{"label":24,"url":25},"Cloudflare config public API","https:\u002F\u002Fgithub.com\u002Fcloudflare\u002Fworkers-sdk\u002Fblob\u002Fmain\u002Fpackages\u002Fconfig\u002Fsrc\u002Fpublic.ts",[27,28,29,30,31],"\u002Fcloudflare-config\u002Fd1","\u002Fcloudflare-config\u002Fr2","\u002Fcloudflare-config\u002Fkv","\u002Fcloudflare-config\u002Fdurable-objects","\u002Fwrangler-to-cf",3,"\u003Ch2 id=\"start-with-a-worker\">Start with a Worker\u003C\u002Fh2>\n\u003Cdiv class=\"code-block\">\u003Cdiv class=\"code-toolbar\">\u003Cspan>cloudflare.config.ts\u003C\u002Fspan>\u003Cbutton type=\"button\" data-copy-code aria-label=\"Copy code\">Copy\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre>\u003Ccode class=\"hljs language-ts\">\u003Cspan class=\"hljs-keyword\">import\u003C\u002Fspan> { defineConfig } \u003Cspan class=\"hljs-keyword\">from\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;cf\u002Fconfig&quot;\u003C\u002Fspan>;\n\n\u003Cspan class=\"hljs-keyword\">export\u003C\u002Fspan> \u003Cspan class=\"hljs-keyword\">default\u003C\u002Fspan> \u003Cspan class=\"hljs-title function_\">defineConfig\u003C\u002Fspan>({\n  \u003Cspan class=\"hljs-attr\">worker\u003C\u002Fspan>: {\n    \u003Cspan class=\"hljs-attr\">name\u003C\u002Fspan>: \u003Cspan class=\"hljs-string\">&quot;notes-worker&quot;\u003C\u002Fspan>,\n    \u003Cspan class=\"hljs-attr\">compatibilityDate\u003C\u002Fspan>: \u003Cspan class=\"hljs-string\">&quot;2026-09-29&quot;\u003C\u002Fspan>,\n    \u003Cspan class=\"hljs-attr\">entrypoint\u003C\u002Fspan>: \u003Cspan class=\"hljs-string\">&quot;.\u002Fsrc\u002Findex.ts&quot;\u003C\u002Fspan>,\n  },\n});\n\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cp>Put this file at your project root. This example describes a plain TypeScript Worker whose source is \u003Ccode>src\u002Findex.ts\u003C\u002Fcode>. It still needs a supported build integration; the config alone is not a build system.\u003C\u002Fp>\n\u003Ch2 id=\"why-typescript\">Why TypeScript?\u003C\u002Fh2>\n\u003Cp>\u003Ccode>defineConfig\u003C\u002Fcode> gives your editor a typed shape for the configuration. Binding helpers expose supported options through autocomplete. The configuration can also be a function, which lets you compute mode-specific values explicitly.\u003C\u002Fp>\n\u003Cp>The new shape uses camelCase fields such as \u003Ccode>compatibilityDate\u003C\u002Fcode>. Copying a Wrangler JSON object into this file without conversion leaves you with the wrong structure. Use \u003Ca href=\"\u002Fwrangler-to-cf\">cf migrate\u003C\u002Fa> for an existing Wrangler project.\u003C\u002Fp>\n\u003Ch2 id=\"add-bindings-under-workerenv\">Add bindings under worker.env\u003C\u002Fh2>\n\u003Cdiv class=\"code-block\">\u003Cdiv class=\"code-toolbar\">\u003Cspan>cloudflare.config.ts\u003C\u002Fspan>\u003Cbutton type=\"button\" data-copy-code aria-label=\"Copy code\">Copy\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre>\u003Ccode class=\"hljs language-ts\">\u003Cspan class=\"hljs-keyword\">import\u003C\u002Fspan> { bindings, defineConfig } \u003Cspan class=\"hljs-keyword\">from\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;cf\u002Fconfig&quot;\u003C\u002Fspan>;\n\n\u003Cspan class=\"hljs-keyword\">export\u003C\u002Fspan> \u003Cspan class=\"hljs-keyword\">default\u003C\u002Fspan> \u003Cspan class=\"hljs-title function_\">defineConfig\u003C\u002Fspan>({\n  \u003Cspan class=\"hljs-attr\">worker\u003C\u002Fspan>: {\n    \u003Cspan class=\"hljs-attr\">name\u003C\u002Fspan>: \u003Cspan class=\"hljs-string\">&quot;notes-worker&quot;\u003C\u002Fspan>,\n    \u003Cspan class=\"hljs-attr\">compatibilityDate\u003C\u002Fspan>: \u003Cspan class=\"hljs-string\">&quot;2026-09-29&quot;\u003C\u002Fspan>,\n    \u003Cspan class=\"hljs-attr\">entrypoint\u003C\u002Fspan>: \u003Cspan class=\"hljs-string\">&quot;.\u002Fsrc\u002Findex.ts&quot;\u003C\u002Fspan>,\n    \u003Cspan class=\"hljs-attr\">env\u003C\u002Fspan>: {\n      \u003Cspan class=\"hljs-attr\">DB\u003C\u002Fspan>: bindings.\u003Cspan class=\"hljs-title function_\">d1\u003C\u002Fspan>({ \u003Cspan class=\"hljs-attr\">name\u003C\u002Fspan>: \u003Cspan class=\"hljs-string\">&quot;notes-db&quot;\u003C\u002Fspan> }),\n      \u003Cspan class=\"hljs-attr\">UPLOADS\u003C\u002Fspan>: bindings.\u003Cspan class=\"hljs-title function_\">r2\u003C\u002Fspan>({ \u003Cspan class=\"hljs-attr\">name\u003C\u002Fspan>: \u003Cspan class=\"hljs-string\">&quot;notes-uploads&quot;\u003C\u002Fspan> }),\n      \u003Cspan class=\"hljs-attr\">API_TOKEN\u003C\u002Fspan>: bindings.\u003Cspan class=\"hljs-title function_\">secret\u003C\u002Fspan>(),\n    },\n  },\n});\n\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cp>\u003Ccode>DB\u003C\u002Fcode>, \u003Ccode>UPLOADS\u003C\u002Fcode> and \u003Ccode>API_TOKEN\u003C\u002Fcode> are application-facing names. The database and bucket names inside the helpers refer to resources. A secret declaration is not a secret value: supply values through the documented deployment or secret-management workflow.\u003C\u002Fp>\n\u003Cp>The focused examples cover \u003Ca href=\"\u002Fcloudflare-config\u002Fd1\">D1\u003C\u002Fa>, \u003Ca href=\"\u002Fcloudflare-config\u002Fr2\">R2\u003C\u002Fa>, \u003Ca href=\"\u002Fcloudflare-config\u002Fkv\">KV\u003C\u002Fa> and \u003Ca href=\"\u002Fcloudflare-config\u002Fdurable-objects\">Durable Objects\u003C\u002Fa>. Use the \u003Ca href=\"\u002Fcloudflare-config-builder\">config builder\u003C\u002Fa> to combine them into a starting point.\u003C\u002Fp>\n\u003Ch2 id=\"select-a-mode-explicitly\">Select a mode explicitly\u003C\u002Fh2>\n\u003Cdiv class=\"code-block\">\u003Cdiv class=\"code-toolbar\">\u003Cspan>cloudflare.config.ts\u003C\u002Fspan>\u003Cbutton type=\"button\" data-copy-code aria-label=\"Copy code\">Copy\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre>\u003Ccode class=\"hljs language-ts\">\u003Cspan class=\"hljs-keyword\">import\u003C\u002Fspan> { bindings, defineConfig } \u003Cspan class=\"hljs-keyword\">from\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;cf\u002Fconfig&quot;\u003C\u002Fspan>;\n\n\u003Cspan class=\"hljs-keyword\">export\u003C\u002Fspan> \u003Cspan class=\"hljs-keyword\">default\u003C\u002Fspan> \u003Cspan class=\"hljs-title function_\">defineConfig\u003C\u002Fspan>(\u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">{ mode }\u003C\u002Fspan>) =&gt;\u003C\u002Fspan> ({\n  \u003Cspan class=\"hljs-attr\">worker\u003C\u002Fspan>: {\n    \u003Cspan class=\"hljs-attr\">name\u003C\u002Fspan>: mode === \u003Cspan class=\"hljs-string\">&quot;production&quot;\u003C\u002Fspan> ? \u003Cspan class=\"hljs-string\">&quot;notes-worker&quot;\u003C\u002Fspan> : \u003Cspan class=\"hljs-string\">&quot;notes-staging&quot;\u003C\u002Fspan>,\n    \u003Cspan class=\"hljs-attr\">compatibilityDate\u003C\u002Fspan>: \u003Cspan class=\"hljs-string\">&quot;2026-09-29&quot;\u003C\u002Fspan>,\n    \u003Cspan class=\"hljs-attr\">entrypoint\u003C\u002Fspan>: \u003Cspan class=\"hljs-string\">&quot;.\u002Fsrc\u002Findex.ts&quot;\u003C\u002Fspan>,\n    \u003Cspan class=\"hljs-attr\">env\u003C\u002Fspan>: {\n      \u003Cspan class=\"hljs-attr\">DB\u003C\u002Fspan>: bindings.\u003Cspan class=\"hljs-title function_\">d1\u003C\u002Fspan>({\n        \u003Cspan class=\"hljs-attr\">name\u003C\u002Fspan>: mode === \u003Cspan class=\"hljs-string\">&quot;production&quot;\u003C\u002Fspan> ? \u003Cspan class=\"hljs-string\">&quot;notes-prod&quot;\u003C\u002Fspan> : \u003Cspan class=\"hljs-string\">&quot;notes-staging&quot;\u003C\u002Fspan>,\n      }),\n    },\n  },\n}));\n\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cp>This example chooses the staging branch whenever the mode is not exactly \u003Ccode>production\u003C\u002Fcode>. Always pass the intended mode and inspect the build result; do not assume the CLI’s default mode is production.\u003C\u002Fp>\n\u003Cp>Support for forwarding \u003Ccode>--mode\u003C\u002Fcode> also depends on the build integration. The \u003Ca href=\"\u002Ferrors\u002Fcf-deploy-mode-nuxt\">Nuxt mode error\u003C\u002Fa> documents one current limitation.\u003C\u002Fp>\n\u003Ch2 id=\"stateful-exports-need-their-own-declaration\">Stateful exports need their own declaration\u003C\u002Fh2>\n\u003Cp>A Durable Object binding points at an exported class. It does not, by itself, declare that class’s storage or lifecycle. The new \u003Ccode>worker.exports\u003C\u002Fcode> map describes that state. See the \u003Ca href=\"\u002Fcloudflare-config\u002Fdurable-objects\">Durable Objects example\u003C\u002Fa> before converting an existing migration history.\u003C\u002Fp>\n\u003Ch2 id=\"common-mistakes\">Common mistakes\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>Using \u003Ccode>main\u003C\u002Fcode> instead of the new \u003Ccode>entrypoint\u003C\u002Fcode> field.\u003C\u002Fli>\n\u003Cli>Placing Wrangler arrays such as \u003Ccode>d1_databases\u003C\u002Fcode> directly under \u003Ccode>worker\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>Supplying a KV namespace title where the helper requires its ID.\u003C\u002Fli>\n\u003Cli>Assuming a valid TypeScript object proves the referenced resource exists.\u003C\u002Fli>\n\u003Cli>Putting plaintext secrets in an executable config that a build may serialize.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>The examples are checked against the installed SDK types. Resource provisioning and remote deployment still require separate validation in your account.\u003C\u002Fp>\n",[35,38,41,44,47,50],{"id":36,"text":37},"start-with-a-worker","Start with a Worker",{"id":39,"text":40},"why-typescript","Why TypeScript?",{"id":42,"text":43},"add-bindings-under-workerenv","Add bindings under worker.env",{"id":45,"text":46},"select-a-mode-explicitly","Select a mode explicitly",{"id":48,"text":49},"stateful-exports-need-their-own-declaration","Stateful exports need their own declaration",{"id":51,"text":52},"common-mistakes","Common mistakes",1790729614466]