void 0.20.2 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. package/README.md +2 -2
  2. package/dist/agents-gni4eqBu.mjs +111 -0
  3. package/dist/auth-3sGB0zJ1.mjs +22 -0
  4. package/dist/{auth-DPl6kck4.mjs → auth-B9_D6ygs.mjs} +6 -241
  5. package/dist/auth-CAw7zHqj.mjs +2 -0
  6. package/dist/auth-client-BWBT8HLp.mjs +6 -0
  7. package/dist/auth-client-Bawdj38n.d.mts +7 -0
  8. package/dist/auth-client-react-7GFffu8R.d.mts +7 -0
  9. package/dist/auth-client-react-CMLwT2xI.mjs +6 -0
  10. package/dist/auth-client-solid-DyTFL4cq.d.mts +7 -0
  11. package/dist/auth-client-solid-UoreJWZG.mjs +6 -0
  12. package/dist/auth-client-svelte-Cv_WvrRk.mjs +6 -0
  13. package/dist/auth-client-svelte-zetW0KIH.d.mts +7 -0
  14. package/dist/auth-client-vue-CFk7Xbv3.mjs +6 -0
  15. package/dist/auth-client-vue-bChShbQP.d.mts +7 -0
  16. package/dist/{auth-cmd-gniL2fNt.mjs → auth-cmd-MkBG2u1f.mjs} +5 -5
  17. package/dist/{auth-link-NZdjCmSc.mjs → auth-link-Devmv96E.mjs} +5 -5
  18. package/dist/{better-auth-shared-DSCeohOK.d.mts → better-auth-shared-BoVwA5Vm.d.mts} +1 -6
  19. package/dist/{better-auth-shared-CYw1T3k4.mjs → better-auth-shared-syGYYmnY.mjs} +1 -1
  20. package/dist/{build-cmd-sI18tX_O.mjs → build-cmd-DsBGwtfs.mjs} +6 -4
  21. package/dist/{cache-IHn5MwBC.mjs → cache-BMw8eMyF.mjs} +6 -4
  22. package/dist/{cancel-deploy-C5qTOdLi.mjs → cancel-deploy-B3_s9NIN.mjs} +5 -3
  23. package/dist/cf-access-rAZxzMkL.mjs +181 -0
  24. package/dist/cf-build-output-CTdlo6Rt.mjs +520 -0
  25. package/dist/cli/cf-compat.d.mts +1 -0
  26. package/dist/cli/cf-compat.mjs +934 -0
  27. package/dist/cli/cli.mjs +61 -38
  28. package/dist/cli/env-schema-probe.mjs +3 -3
  29. package/dist/client-DAAivdid.mjs +2 -0
  30. package/dist/{client-dHfSJvAN.mjs → client-PdAJ-F0t.mjs} +148 -89
  31. package/dist/{cloudflare-auth-6M5llVPC.mjs → cloudflare-auth-BCmTc1X_.mjs} +13 -44
  32. package/dist/{cloudflare-cmd-4RPGN3KB.mjs → cloudflare-cmd-D6PrKn7o.mjs} +4 -7
  33. package/dist/{cloudflare-connect-t1UU5svD.mjs → cloudflare-connect-DloREDlc.mjs} +6 -6
  34. package/dist/cloudflare-operations-BHNJVDbN.mjs +2 -0
  35. package/dist/{cloudflare-operations-BzWnlC1_.mjs → cloudflare-operations-CPEdHYhM.mjs} +37 -39
  36. package/dist/cloudflare-user-output-Q-k0QoNQ.mjs +20 -0
  37. package/dist/collect-DAUItMDS.mjs +2 -0
  38. package/dist/collect-DXHNWHcT.mjs +48 -0
  39. package/dist/config--T87TD8T.mjs +2 -0
  40. package/dist/{config-NOG_U1aK.mjs → config-BSe70f4T.mjs} +4 -6
  41. package/dist/config-DDIFxQYx.mjs +2 -0
  42. package/dist/{config-uNGuFsI2.mjs → config-Dxr6cTXn.mjs} +22 -37
  43. package/dist/config-DywxBLQC.d.mts +185 -0
  44. package/dist/config-entry.d.mts +6 -0
  45. package/dist/config-entry.mjs +7 -0
  46. package/dist/config-uP7ZDtVZ.mjs +21 -0
  47. package/dist/config-write-y3CBI_ux.mjs +60 -0
  48. package/dist/{connect-Bfk31O_8.mjs → connect-BvC9kolB.mjs} +8 -6
  49. package/dist/{create-project-Bk9Z0-Jg.mjs → create-project-C9lQhRzj.mjs} +9 -25
  50. package/dist/create-project-CI-17RVJ.mjs +2 -0
  51. package/dist/database-provider-Cx525bwX.mjs +6 -0
  52. package/dist/database-provider.mjs +1 -5
  53. package/dist/{db-BkRoptAt.mjs → db-R7IQgOv5.mjs} +48 -44
  54. package/dist/{delete-DouASY9P.mjs → delete-CghI_NXn.mjs} +6 -4
  55. package/dist/deploy-CYPymbtG.mjs +2 -0
  56. package/dist/{deploy-DTaWUS1S.mjs → deploy-H968Lo4T.mjs} +765 -197
  57. package/dist/discover-BBzDZe_o.mjs +2 -0
  58. package/dist/{discover-xvfrgJeo.mjs → discover-C4O6YxVS.mjs} +3 -8
  59. package/dist/{dist-BrsS7cai.mjs → dist-4WkAWhWx.mjs} +1 -15
  60. package/dist/{dist-m40_XgNh.mjs → dist-Bn8Kodjp.mjs} +1 -1
  61. package/dist/dist-C5fND3R0.mjs +2 -0
  62. package/dist/dist-D7-nEOXi.mjs +2 -0
  63. package/dist/{output-B0cfNSx5.mjs → dist-Dn6nn2IU.mjs} +3 -926
  64. package/dist/{domain-1RhhOVrC.mjs → domain-CITt8lC-.mjs} +7 -5
  65. package/dist/{route-types-Da-DpyUp.mjs → drizzle-Beb2Am5S.mjs} +1 -280
  66. package/dist/{email-Ce6SQq-i.mjs → email-C5kaZXzJ.mjs} +2 -2
  67. package/dist/{email-C-lGh51B.mjs → email-_8VmyX7V.mjs} +14 -12
  68. package/dist/{entry-DU3oDoQ3.mjs → entry-DdRFGK0y.mjs} +2 -2
  69. package/dist/{env-DJHsPE7Z.mjs → env-DV4r3nHz.mjs} +9 -7
  70. package/dist/{env-DBKmK4vc.mjs → env-DX_v-Q-v.mjs} +1 -1
  71. package/dist/env-Yz4HcvHs.mjs +78 -0
  72. package/dist/env-helpers--wFmQ_5Q.mjs +136 -0
  73. package/dist/{env-types-BNPhro-M.mjs → env-types-CWDtqHgw.mjs} +6 -2
  74. package/dist/{env-validation-CF6KvTRf.mjs → env-validation-BsFEXps5.mjs} +19 -28
  75. package/dist/env-validation-DIDGM7h4.mjs +2 -0
  76. package/dist/fetch-CXDChK7B.mjs +18 -0
  77. package/dist/fetch-_SeGZao9.d.mts +57 -0
  78. package/dist/fetch-stream-AOByI7Ki.mjs +81 -0
  79. package/dist/fetch-stream-Bjf0hoZb.d.mts +49 -0
  80. package/dist/gen-BBiIZw6g.mjs +2 -0
  81. package/dist/{gen-B_wPnVTK.mjs → gen-CFOEEc-t.mjs} +13 -11
  82. package/dist/{generate-RTK8_kK1.mjs → generate-C0VY6RVf.mjs} +2 -2
  83. package/dist/{github-cmd-PW7ZnWTp.mjs → github-cmd-jYjha2LO.mjs} +18 -22
  84. package/dist/{handler-D1hLsObx.d.mts → handler-BXJTXd02.d.mts} +6 -1
  85. package/dist/handler-DghKr6dU.mjs +150 -0
  86. package/dist/head-D_QRR5Yd.mjs +112 -0
  87. package/dist/head-client-DzmJGN4C.mjs +90 -0
  88. package/dist/{headers-BAHwgHdW.mjs → headers-B_HBMgi0.mjs} +2 -2
  89. package/dist/{help-CwOX-zmI.mjs → help-C46mnlUS.mjs} +17 -12
  90. package/dist/help-CS_nAsWu.mjs +2 -0
  91. package/dist/index.d.mts +2 -20
  92. package/dist/index.mjs +116 -60
  93. package/dist/{init-BWZ7q5Z4.mjs → init-CSXmvxKu.mjs} +49 -50
  94. package/dist/{link-Rmvu2Wl_.mjs → link-DxMOALXk.mjs} +7 -5
  95. package/dist/{list-DEE2S6mY.mjs → list-0wQs0oYg.mjs} +7 -5
  96. package/dist/live-CB1y5IuC.mjs +411 -0
  97. package/dist/live-CKiJilLr.d.mts +105 -0
  98. package/dist/local-d1-DzykTWY8.mjs +104 -0
  99. package/dist/{login-Uvferzmm.mjs → login-CKk5NX4d.mjs} +6 -11
  100. package/dist/login-Ch9cgWRF.mjs +2 -0
  101. package/dist/{logs-27FenuiC.mjs → logs-hxWBSoej.mjs} +6 -4
  102. package/dist/migrate-CLty4mZR.mjs +2 -0
  103. package/dist/migrate-DcW8F2W8.mjs +285 -0
  104. package/dist/migration-handler-DM4clYj5.d.mts +51 -0
  105. package/dist/{neon-DHwd2zvC.mjs → neon-n74ta1Pr.mjs} +1 -1
  106. package/dist/{node-Ez5KW5rn.mjs → node-Cupyf7-s.mjs} +6 -6
  107. package/dist/{operator-auth-B3e08unv.mjs → operator-auth-BkVgJqv-.mjs} +2 -2
  108. package/dist/{operator-client-LUZnlnYk.mjs → operator-client-A0iex2yi.mjs} +2 -1
  109. package/dist/{operator-cmd-CjOTmAYE.mjs → operator-cmd-BEUYhaHB.mjs} +6 -6
  110. package/dist/output-urU86XeT.mjs +146 -0
  111. package/dist/{package-json-CPoWX79C.mjs → package-json-iCbMg5XF.mjs} +1 -1
  112. package/dist/pages/client.d.mts +5 -2
  113. package/dist/pages/client.mjs +5 -3
  114. package/dist/pages/head-client.mjs +1 -89
  115. package/dist/pages/head.mjs +1 -111
  116. package/dist/pages/index.d.mts +2 -3
  117. package/dist/pages/index.mjs +7 -7
  118. package/dist/pages/islands-plugin.mjs +2 -2
  119. package/dist/pages/prefetch.d.mts +2 -30
  120. package/dist/pages/prefetch.mjs +1 -89
  121. package/dist/pages/protocol.d.mts +2 -2
  122. package/dist/pages/protocol.mjs +3 -3
  123. package/dist/pages/serialize.d.mts +2 -9
  124. package/dist/pages/serialize.mjs +1 -13
  125. package/dist/plan-BEZ8VJW0.mjs +256 -0
  126. package/dist/plan-DpuOr14e.mjs +2 -0
  127. package/dist/{platform-auth-config-DrbQXXiW.mjs → platform-auth-config-Df6yVw-e.mjs} +6 -6
  128. package/dist/{platform-auth-protection-Bhtvp0B_.mjs → platform-auth-protection-Jb0yftay.mjs} +7 -5
  129. package/dist/{platform-auth-recovery-CeOKGVeJ.mjs → platform-auth-recovery-DmRyIfW0.mjs} +6 -5
  130. package/dist/platform-cmd-C9Vt7m-d.mjs +2 -0
  131. package/dist/{platform-cmd-BFhieCdV.mjs → platform-cmd-DRxCOTwy.mjs} +8 -5
  132. package/dist/{platform-domain-C74PULqV.mjs → platform-domain-IjiXgrXJ.mjs} +4 -3
  133. package/dist/{platform-lifecycle-BwAIgz-t.mjs → platform-lifecycle-BquAaU-5.mjs} +263 -56
  134. package/dist/platform-lifecycle-CuJIZNvA.mjs +2 -0
  135. package/dist/{platform-management-COogu_Se.mjs → platform-management-CCQKGsq4.mjs} +12 -7
  136. package/dist/platform-management-Cgyed0WY.mjs +2 -0
  137. package/dist/{platform-recovery-ewqLefp1.mjs → platform-recovery-DS8ih1SW.mjs} +3 -3
  138. package/dist/platform-registry-BJbgZLS1.mjs +431 -0
  139. package/dist/{plugin-inference-BDRfZngg.mjs → plugin-inference-DsvtJLll.mjs} +4 -4
  140. package/dist/prefetch-Bsc_Pb6c.mjs +90 -0
  141. package/dist/prefetch-Ce6la4EI.d.mts +31 -0
  142. package/dist/{prepare-blNRQvQl.mjs → prepare-CaUxODOU.mjs} +3 -2
  143. package/dist/prepare-D4CkM3_v.mjs +2 -0
  144. package/dist/{prepare-CtDJjoOj.mjs → prepare-pcWcxSCh.mjs} +13 -11
  145. package/dist/prerender-render-Cf_WDE9W.mjs +111 -0
  146. package/dist/prerender-render.mjs +1 -110
  147. package/dist/{preset-lAy0B0BQ.mjs → preset-Dowh9tTt.mjs} +16 -118
  148. package/dist/project-BEBFDFLz.mjs +2 -0
  149. package/dist/project-CWNIPoXc.mjs +209 -0
  150. package/dist/{project-cmd-DmZK9Hxf.mjs → project-cmd-2lN--YAX.mjs} +18 -16
  151. package/dist/{project-paths-SK8nMHPp.mjs → project-paths-CKQ-Q5JS.mjs} +47 -14
  152. package/dist/project-slug-23TpquG4.mjs +8 -0
  153. package/dist/project-slug-DofjTFd-.mjs +2 -0
  154. package/dist/{project-team-D8jOJMUJ.mjs → project-team-Dapn9HZn.mjs} +9 -5
  155. package/dist/{project-token-DA34bf-C.mjs → project-token-C90v9SJK.mjs} +6 -4
  156. package/dist/{project-tsconfig-Ql2XsSQp.mjs → project-tsconfig-CwfqUnVp.mjs} +2 -2
  157. package/dist/{protocol-C-pqYJjE.d.mts → protocol-ZH3jP4a7.d.mts} +1 -1
  158. package/dist/providers-BNKRacMr.d.mts +7 -0
  159. package/dist/provision-CNgEBkVA.mjs +3 -0
  160. package/dist/{provision-CSJOjjQk.mjs → provision-Cck2m3jJ.mjs} +11 -25
  161. package/dist/queues-BWKt1Xo4.d.mts +7 -0
  162. package/dist/{requests-CUExwGQQ.mjs → requests-CzX46I0i.mjs} +5 -3
  163. package/dist/resolve-project-BTotl8Nn.mjs +2 -0
  164. package/dist/{resolve-project--Vxawf7z.mjs → resolve-project-Xvis70DG.mjs} +2 -8
  165. package/dist/response-Tn7rU0MV.mjs +30 -0
  166. package/dist/{rollback-CDNGU1gr.mjs → rollback-BEeyc73H.mjs} +6 -4
  167. package/dist/{rolldown-runtime-rQ84J-ij.mjs → rolldown-runtime-DXIUcv95.mjs} +1 -10
  168. package/dist/route-types-Id82-veQ.mjs +280 -0
  169. package/dist/{local-d1-D2I6Ox5F.mjs → runner-BGVsGgkb.mjs} +6 -114
  170. package/dist/runner-CQs_cDSG.mjs +2 -0
  171. package/dist/runner-mysql-1o47achK.mjs +2 -0
  172. package/dist/{runner-mysql-7BPUNGmL.mjs → runner-mysql-BhwMk2Bm.mjs} +2 -9
  173. package/dist/{runner-pg-BkEza-dX.mjs → runner-pg-CJ_JeGF6.mjs} +2 -9
  174. package/dist/runner-pg-D7z01mQS.mjs +2 -0
  175. package/dist/runtime/ai.mjs +1 -1
  176. package/dist/runtime/auth-client-react.d.mts +2 -6
  177. package/dist/runtime/auth-client-react.mjs +1 -5
  178. package/dist/runtime/auth-client-solid.d.mts +2 -6
  179. package/dist/runtime/auth-client-solid.mjs +1 -5
  180. package/dist/runtime/auth-client-svelte.d.mts +2 -6
  181. package/dist/runtime/auth-client-svelte.mjs +1 -5
  182. package/dist/runtime/auth-client-vue.d.mts +2 -6
  183. package/dist/runtime/auth-client-vue.mjs +1 -5
  184. package/dist/runtime/auth-client.d.mts +2 -6
  185. package/dist/runtime/auth-client.mjs +1 -5
  186. package/dist/runtime/auth.mjs +1 -21
  187. package/dist/runtime/better-auth-mysql.d.mts +1 -1
  188. package/dist/runtime/better-auth-mysql.mjs +1 -1
  189. package/dist/runtime/better-auth-pg.d.mts +1 -1
  190. package/dist/runtime/better-auth-pg.mjs +1 -1
  191. package/dist/runtime/better-auth.d.mts +1 -1
  192. package/dist/runtime/better-auth.mjs +1 -1
  193. package/dist/runtime/client-react.d.mts +3 -3
  194. package/dist/runtime/client-react.mjs +3 -3
  195. package/dist/runtime/client-solid.d.mts +3 -3
  196. package/dist/runtime/client-solid.mjs +3 -3
  197. package/dist/runtime/client-svelte.d.mts +3 -3
  198. package/dist/runtime/client-svelte.mjs +3 -3
  199. package/dist/runtime/client-vue.d.mts +3 -3
  200. package/dist/runtime/client-vue.mjs +3 -3
  201. package/dist/runtime/client.d.mts +3 -3
  202. package/dist/runtime/client.mjs +3 -3
  203. package/dist/runtime/db.mjs +1 -1
  204. package/dist/runtime/durable.mjs +1 -1
  205. package/dist/runtime/email/testing.mjs +1 -1
  206. package/dist/runtime/env-helpers.mjs +1 -135
  207. package/dist/runtime/env-public-client.mjs +1 -1
  208. package/dist/runtime/env-public.mjs +2 -2
  209. package/dist/runtime/env.mjs +1 -77
  210. package/dist/runtime/fetch-stream.d.mts +2 -49
  211. package/dist/runtime/fetch-stream.mjs +2 -80
  212. package/dist/runtime/fetch.d.mts +2 -57
  213. package/dist/runtime/fetch.mjs +2 -17
  214. package/dist/runtime/handler.d.mts +1 -1
  215. package/dist/runtime/handler.mjs +1 -149
  216. package/dist/runtime/kv.mjs +1 -1
  217. package/dist/runtime/live-client.d.mts +1 -1
  218. package/dist/runtime/live-server.mjs +2 -2
  219. package/dist/runtime/live.d.mts +2 -104
  220. package/dist/runtime/live.mjs +1 -410
  221. package/dist/runtime/migration-handler-mysql.d.mts +1 -1
  222. package/dist/runtime/migration-handler-pg.d.mts +1 -1
  223. package/dist/runtime/migration-handler.d.mts +2 -50
  224. package/dist/runtime/queues.d.mts +2 -6
  225. package/dist/runtime/queues.mjs +1 -1
  226. package/dist/runtime/remote/index.mjs +49 -8
  227. package/dist/runtime/response.mjs +1 -29
  228. package/dist/runtime/sandbox.d.mts +4 -56
  229. package/dist/runtime/sandbox.mjs +82 -221
  230. package/dist/runtime/sse.mjs +1 -171
  231. package/dist/runtime/storage.mjs +1 -1
  232. package/dist/runtime/validator.d.mts +1 -1
  233. package/dist/runtime/validator.mjs +1 -71
  234. package/dist/runtime/ws-server.d.mts +2 -2
  235. package/dist/runtime/ws-server.mjs +2 -2
  236. package/dist/runtime/ws.d.mts +2 -121
  237. package/dist/{scan-CpK-57ug.mjs → scan-DJbooZm2.mjs} +3 -3
  238. package/dist/{scan-BMH4rzlv.mjs → scan-DdDvRCU1.mjs} +8 -26
  239. package/dist/{secret-Bzzi2e9E.mjs → secret-wnTel5Yw.mjs} +8 -6
  240. package/dist/serialize-BPvnNQuA.mjs +14 -0
  241. package/dist/serialize-CfSwWfF2.d.mts +10 -0
  242. package/dist/{skills-C0RvGjeE.mjs → skills-B-690E7h.mjs} +3 -2
  243. package/dist/sse-BaC1jXko.mjs +172 -0
  244. package/dist/{subcommand-prompt-Bmyn5Rlc.mjs → subcommand-prompt-Gj3VzLIh.mjs} +2 -1
  245. package/dist/sveltekit.d.mts +2 -1
  246. package/dist/sveltekit.mjs +3 -2
  247. package/dist/validate-DqJ33oHj.mjs +2 -0
  248. package/dist/validate-qNhV00PD.mjs +180 -0
  249. package/dist/validator-BTOu0fB0.mjs +72 -0
  250. package/dist/{wrangler--imS8n0d.mjs → wrangler-D01qs6VB.mjs} +259 -71
  251. package/dist/ws-BwcqizuH.d.mts +122 -0
  252. package/dist/{yarn-pnp-DxSInkzL.mjs → yarn-pnp-CVEc3gE7.mjs} +1 -1
  253. package/package.json +19 -8
  254. package/skills/void/SKILL.md +7 -5
  255. package/skills/void/docs/guide/ai.md +3 -3
  256. package/skills/void/docs/guide/app-types.md +12 -11
  257. package/skills/void/docs/guide/auth.md +2 -2
  258. package/skills/void/docs/guide/database/d1.md +1 -1
  259. package/skills/void/docs/guide/database/mysql.md +1 -1
  260. package/skills/void/docs/guide/database/postgresql.md +3 -3
  261. package/skills/void/docs/guide/deployment.md +16 -16
  262. package/skills/void/docs/guide/durable-state.md +2 -2
  263. package/skills/void/docs/guide/edge/headers.md +3 -3
  264. package/skills/void/docs/guide/edge/prerendering.md +1 -1
  265. package/skills/void/docs/guide/edge/redirects.md +4 -4
  266. package/skills/void/docs/guide/edge/revalidation.md +6 -6
  267. package/skills/void/docs/guide/edge/rewrites.md +28 -27
  268. package/skills/void/docs/guide/edge/static-assets.md +1 -1
  269. package/skills/void/docs/guide/email.md +27 -25
  270. package/skills/void/docs/guide/env-migration.md +1 -1
  271. package/skills/void/docs/guide/index.md +1 -1
  272. package/skills/void/docs/guide/pages-routing/head.md +1 -1
  273. package/skills/void/docs/guide/platform/administration/access.md +171 -0
  274. package/skills/void/docs/guide/platform/administration/email.md +121 -0
  275. package/skills/void/docs/guide/platform/administration/operations.md +97 -0
  276. package/skills/void/docs/guide/platform/administration/projects.md +56 -0
  277. package/skills/void/docs/guide/platform/development/local.md +119 -0
  278. package/skills/void/docs/guide/platform/development/runtime.md +124 -0
  279. package/skills/void/docs/guide/platform/development/schema-ci.md +95 -0
  280. package/skills/void/docs/guide/platform/installation/ci.md +58 -0
  281. package/skills/void/docs/guide/platform/installation/credentials.md +90 -0
  282. package/skills/void/docs/guide/platform/installation/domains.md +68 -0
  283. package/skills/void/docs/guide/platform/installation/first-deployment.md +82 -0
  284. package/skills/void/docs/guide/platform/installation/maintenance.md +137 -0
  285. package/skills/void/docs/guide/platform/installation/prerequisites.md +88 -0
  286. package/skills/void/docs/guide/platform/installation/setup.md +169 -0
  287. package/skills/void/docs/guide/platform/installation/uninstall.md +54 -0
  288. package/skills/void/docs/guide/platform-administration.md +6 -414
  289. package/skills/void/docs/guide/platform-development.md +5 -316
  290. package/skills/void/docs/guide/project-collaboration.md +1 -1
  291. package/skills/void/docs/guide/remote-dev.md +2 -2
  292. package/skills/void/docs/guide/sandboxes.md +10 -25
  293. package/skills/void/docs/guide/self-hosted-platform.md +11 -694
  294. package/skills/void/docs/guide/ssg.md +1 -1
  295. package/skills/void/docs/guide/websockets.md +1 -1
  296. package/skills/void/docs/integrations/cloudflare.md +86 -84
  297. package/skills/void/docs/integrations/frameworks/analog.md +14 -9
  298. package/skills/void/docs/integrations/frameworks/astro.md +14 -10
  299. package/skills/void/docs/integrations/frameworks/nuxt.md +14 -9
  300. package/skills/void/docs/integrations/frameworks/overview.md +35 -29
  301. package/skills/void/docs/integrations/frameworks/react-router.md +1 -1
  302. package/skills/void/docs/integrations/frameworks/sveltekit.md +33 -30
  303. package/skills/void/docs/integrations/frameworks/tanstack-start.md +1 -1
  304. package/skills/void/docs/integrations/nodejs-bun-deno.md +5 -5
  305. package/skills/void/docs/reference/api.md +55 -38
  306. package/skills/void/docs/reference/cli.md +60 -34
  307. package/skills/void/docs/reference/config.md +57 -34
  308. package/skills/void/docs/reference/resource-inference.md +10 -10
  309. package/skills/void/docs/reference/structure.md +2 -2
  310. package/dist/validate-tBBN_dXH.mjs +0 -505
@@ -4,7 +4,7 @@ outline: deep
4
4
 
5
5
  # Static Site Generation (SSG)
6
6
 
7
- Set `output: "static"` in `void.json` to prerender all pages at build time:
7
+ Set `output: "static"` in `void.config.ts` to prerender all pages at build time:
8
8
 
9
9
  ```json
10
10
  {
@@ -196,6 +196,6 @@ Each socket connects to one route instance. Applications that need to switch roo
196
196
 
197
197
  ## Deployment
198
198
 
199
- `void deploy --platform cloudflare` persists the required binding and append-only SQLite class migration in `wrangler.jsonc`, then deploys the generated Worker directly to your account. Commit this migration history and never delete or reorder a step after deployment.
199
+ `void deploy --platform cloudflare` persists the required binding and append-only SQLite class migration in `void.lock.json`, then deploys the generated Worker directly to your account. Commit this migration history and never delete or reorder a step after deployment.
200
200
 
201
201
  `void deploy --platform void` uses the same shared migration planner in the hosted uploader. Existing hosted WebSocket classes created on legacy storage remain there; only genuinely new classes use SQLite.
@@ -94,14 +94,16 @@ This augments the `Cloudflare.Env` interface with `DB`, `KV`, `STORAGE`, `AI`, a
94
94
  | `QUEUE_*` | `Queue<T>` | `defineQueue()` or `import { queues } from "void/queues"` |
95
95
  | filename-derived | `DurableObjectNamespace` | module in `durable-objects/` |
96
96
 
97
- Bindings are [inferred automatically](../reference/resource-inference.md) by scanning your source files for import and access patterns. You can also set them explicitly in `void.json`:
97
+ Bindings are [inferred automatically](../reference/resource-inference.md) by scanning your source files for import and access patterns. You can also set them explicitly in `void.config.ts`:
98
98
 
99
- ```json
100
- {
101
- "inference": {
102
- "bindings": { "db": true, "kv": true, "storage": false, "ai": "MY_AI" }
103
- }
104
- }
99
+ ```ts
100
+ import { defineConfig } from 'void/config';
101
+
102
+ export default defineConfig({
103
+ inference: {
104
+ bindings: { db: true, kv: true, storage: false, ai: 'MY_AI' },
105
+ },
106
+ });
105
107
  ```
106
108
 
107
109
  `db`, `kv`, `storage`, and `ai` accept a string to customize the binding name (for example, `"db": "MY_DB"` or `"ai": "MY_AI"`). `email` is a boolean feature switch.
@@ -110,15 +112,17 @@ See [Configuration](../reference/config.md) for details.
110
112
 
111
113
  ### Cloudflare configuration passthrough
112
114
 
113
- You can set non-binding Cloudflare fields like `compatibility_date` and `compatibility_flags` in `void.json`:
115
+ You can set non-binding Cloudflare fields like `compatibility_date` and `compatibility_flags` in `void.config.ts`:
114
116
 
115
- ```json
116
- {
117
- "worker": {
118
- "compatibility_date": "2026-02-24",
119
- "compatibility_flags": ["nodejs_compat"]
120
- }
121
- }
117
+ ```ts
118
+ import { defineConfig } from 'void/config';
119
+
120
+ export default defineConfig({
121
+ worker: {
122
+ compatibility_date: '2026-02-24',
123
+ compatibility_flags: ['nodejs_compat'],
124
+ },
125
+ });
122
126
  ```
123
127
 
124
128
  For environment variables, declare the schema in `env.ts` and put local values in the single root `.env` file. Void loads `.env` into local development bindings only; it never becomes production configuration:
@@ -128,71 +132,69 @@ For environment variables, declare the schema in `env.ts` and put local values i
128
132
  API_URL=https://api.example.com
129
133
  ```
130
134
 
131
- Binding arrays such as `d1_databases`, `kv_namespaces`, and `r2_buckets` are not allowed in the `worker` field because Void manages bindings for you. If you need custom bindings with real resource IDs, add a `wrangler.jsonc` to the project root instead. See [Cloudflare config merging](#cloudflare-config-merging) for details.
135
+ Binding arrays such as `d1_databases`, `kv_namespaces`, and `r2_buckets` belong in the `cloudflare` field. Void adds inferred bindings that are missing by name and preserves custom bindings with real resource IDs. See [Cloudflare config merging](#cloudflare-config-merging) for details.
132
136
 
133
- For non-secret plain-text defaults, you can also set `worker.vars` in `void.json`. Local `.env` values override `worker.vars` during development. Production builds reject any `worker.vars` name that is declared as a server key in `env.ts`; store those values remotely with `void secret put` instead.
137
+ For non-secret plain-text defaults, you can also set `worker.vars` in `void.config.ts`. Local `.env` values override `worker.vars` during development. Production builds reject any `worker.vars` name that is declared as a server key in `env.ts`; store those values remotely with `void secret put` instead.
134
138
 
135
139
  ## Cloudflare config merging
136
140
 
137
- By default, Void configures the Cloudflare plugin programmatically, so you don't need a `wrangler.jsonc` for bindings. Void pins a Workers compatibility date in `void.json` `worker.compatibility_date`; if no date is already configured in `void.json` or `wrangler.jsonc`/`wrangler.json`, Void writes the latest known-good date to `void.json`. Bindings are inferred from your source code and provisioned with local placeholder IDs for development.
141
+ Void reads `void.config.ts`, combines its `cloudflare` settings with provisioned values in `void.lock.json`, and generates the Cloudflare config needed by the build and deploy tools. Root `wrangler.jsonc` and `wrangler.json` files from existing apps are migrated automatically by `void init` or `void deploy`. Bindings are inferred from source code and use local placeholder IDs for development.
138
142
 
139
- If you add a `wrangler.jsonc` (or `wrangler.json`) to your project root, Void respects it -- but **how** depends on whether Void owns the Cloudflare integration or a meta-framework does.
143
+ Edit `cloudflare` in `void.config.ts` for custom Worker settings. Commit `void.lock.json` when Void records resource IDs or Durable Object migration history.
140
144
 
141
145
  ### Void-only mode and Vite-based frameworks
142
146
 
143
- In Void's default mode and when using frameworks where Void controls the Cloudflare integration (TanStack Start, React Router), Void manages the `@cloudflare/vite-plugin` directly. It passes a `config` callback that merges inferred bindings into whatever the plugin resolves from your `wrangler.jsonc`:
147
+ In Void's default mode and frameworks where Void controls the Cloudflare integration (TanStack Start, React Router), Void manages `@cloudflare/vite-plugin` directly. It merges inferred bindings with the generated Cloudflare config:
144
148
 
145
- 1. The plugin reads your `wrangler.jsonc` and resolves it into a config object with `d1_databases`, `kv_namespaces`, `r2_buckets`, etc.
149
+ 1. The plugin reads the generated config containing your `cloudflare` settings and Void's recorded resource values.
146
150
  2. Void checks each inferred binding **by name** (e.g. `"DB"`, `"KV"`, `"STORAGE"`). If a binding with that name already exists in your config, it is left untouched.
147
151
  3. Only bindings that are **missing** from your config are added with local placeholder IDs (e.g. `database_id: "local"`).
148
152
  4. The merged config is used for both `vite dev` (Miniflare) and `vite build` (output `wrangler.json` in `dist/`).
149
153
 
150
- All other fields in your `wrangler.jsonc` -- `name`, `routes`, `services`, `vars`, `env`, `compatibility_date`, etc. -- are preserved in the resolved config and flow through to the build output.
154
+ All other `cloudflare` fields -- `name`, `routes`, `services`, `vars`, `env`, `compatibility_date`, etc. -- flow through to the build output.
151
155
 
152
156
  Fields that Void always sets (`main`, `triggers`, `assets`) don't need to be in your Cloudflare config -- they're added programmatically based on your project structure.
153
157
 
154
- In this mode, normal inferred bindings are merged purely in memory. Typed state modules in `durable-objects/` are the exception: Void persists their bindings and `new_sqlite_classes` entries to `wrangler.jsonc` because Cloudflare Durable Object migration history must remain append-only across builds. Commit those entries.
158
+ In this mode, normal inferred bindings are merged in memory. Typed state modules in `durable-objects/` are the exception: Void records their bindings and append-only `new_sqlite_classes` history in `void.lock.json`. Commit the lock.
155
159
 
156
160
  ### Adapter-based frameworks (SvelteKit, Nuxt, Astro)
157
161
 
158
162
  When using SvelteKit, Nuxt, or Astro, the framework's own Cloudflare adapter owns the worker build and dev server. Void does **not** provide `@cloudflare/vite-plugin` in that setup. It only contributes DB type codegen, migration management, and binding sync.
159
163
 
160
- Because Void doesn't control the CF plugin in this mode, it can't merge bindings via a config callback. Instead, on dev startup Void syncs inferred bindings directly to your `wrangler.jsonc` file on disk:
164
+ Because Void does not control the Cloudflare plugin in this mode, it syncs inferred bindings to the generated Cloudflare config on dev startup:
161
165
 
162
166
  - Only adds bindings that are **missing** by name -- existing bindings are never modified or removed.
163
- - If `worker.compatibility_date` is set in `void.json`, syncs that date into the Cloudflare config so the framework adapter reads the same value.
167
+ - If `worker.compatibility_date` is set in `void.config.ts`, syncs that date into the Cloudflare config so the framework adapter reads the same value.
164
168
  - Also ensures the `nodejs_als` compatibility flag is present.
165
- - The framework adapter then reads this `wrangler.jsonc` normally.
169
+ - The framework adapter reads the generated config through its configured path.
166
170
 
167
- The framework adapter reads bindings from `wrangler.jsonc`. Void adds them as you import resources, and `void deploy --platform cloudflare` replaces local placeholder IDs when it provisions production resources.
171
+ The framework adapter reads the generated config. Void adds bindings as you import resources, and `void deploy --platform cloudflare` replaces local placeholder IDs when it provisions production resources.
168
172
 
169
173
  ### Merge precedence
170
174
 
171
- | Source | Priority | What it controls |
172
- | -------------------------- | -------------------- | ------------------------------------------------------------------- |
173
- | Your `wrangler.jsonc` | Highest for bindings | Real resource IDs, service bindings, routes, vars, environments |
174
- | `void.json` `worker` field | Highest for compat | `compatibility_date`, `compatibility_flags`, `vars` |
175
- | Void inference | Fills gaps only | Adds placeholder bindings for inferred resources not in your config |
175
+ | Source | Priority | What it controls |
176
+ | ------------------------------- | ----------------------------- | ------------------------------------------------------------------- |
177
+ | `void.config.ts` `cloudflare` | Highest for authored settings | Resource IDs, service bindings, routes, vars, environments |
178
+ | `void.config.ts` `worker` field | Highest for compat | `compatibility_date`, `compatibility_flags`, `vars` |
179
+ | Void inference | Fills gaps only | Adds placeholder bindings for inferred resources not in your config |
176
180
 
177
- If no date is found in `void.json`, the project Cloudflare config, or the supported generated build fallback during deploy, Void pins the latest known-good date to `void.json` and uses it for that run.
181
+ If no date is found in `void.config.ts` or the generated build config, Void records the latest known-good date and uses it for that run.
178
182
 
179
183
  ### Example
180
184
 
181
- If your code uses `c.env.DB` and `c.env.KV`, and your `wrangler.jsonc` only defines D1:
185
+ If your code uses `c.env.DB` and `c.env.KV`, and `cloudflare` only defines D1:
182
186
 
183
- ```jsonc
184
- {
185
- "name": "my-app",
186
- "d1_databases": [
187
- {
188
- "binding": "DB",
189
- "database_name": "my-app-db",
190
- "database_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
191
- },
192
- ],
193
- // Service bindings, routes, etc. are also preserved
194
- "services": [{ "binding": "API", "service": "my-api-worker" }],
195
- }
187
+ ```ts
188
+ // Inside defineConfig({ ... })
189
+ cloudflare: {
190
+ name: 'my-app',
191
+ d1_databases: [{
192
+ binding: 'DB',
193
+ database_name: 'my-app-db',
194
+ database_id: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
195
+ }],
196
+ services: [{ binding: 'API', service: 'my-api-worker' }],
197
+ },
196
198
  ```
197
199
 
198
200
  Void sees that `DB` is already configured and leaves it alone (including your real `database_id`), but adds a local placeholder for `KV` since it's missing. The `services` array passes through unchanged.
@@ -203,7 +205,7 @@ This means `pnpm dev` works out of the box (Miniflare creates local instances of
203
205
 
204
206
  After `vite build`, the Cloudflare Vite plugin writes a merged `wrangler.json` to the `dist/` directory. This file contains:
205
207
 
206
- - All fields from your `wrangler.jsonc` (bindings with real IDs, routes, services, vars, environments)
208
+ - All `cloudflare` fields from `void.config.ts` (bindings with real IDs, routes, services, vars, environments)
207
209
  - Any inferred bindings Void added (local placeholders during development; provisioned IDs during deploy)
208
210
  - Fields set by Void (`main`, `assets`, `triggers`)
209
211
 
@@ -221,7 +223,7 @@ Choose Cloudflare during `void init`, then deploy:
221
223
  void deploy
222
224
  ```
223
225
 
224
- Void opens your browser to sign in when needed. If you have access to several accounts, it asks which one to use and saves the account in your root `wrangler.jsonc`. Credentials are stored in your operating system's keychain. Press Ctrl+C to cancel login, or manage your session with `void cloudflare login`, `status`, and `logout`.
226
+ Void opens your browser to sign in when needed. If you have access to several accounts, it asks which one to use and records the account in `void.lock.json`. Credentials are stored in your operating system's keychain. Press Ctrl+C to cancel login, or manage your session with `void cloudflare login`, `status`, and `logout`.
225
227
 
226
228
  To configure deployment separately from project setup, run `void connect --platform cloudflare`. It uses the same browser login and account selection as `void init`, and saves Cloudflare as the target for subsequent `void deploy` commands.
227
229
 
@@ -237,7 +239,7 @@ This deploys directly to your account. You don't need a Void platform connection
237
239
 
238
240
  ### Deploy an existing Worker
239
241
 
240
- This handoff is for the existing source of an app already built with Void and previously deployed directly to Cloudflare. Keep its `wrangler.jsonc` or `wrangler.json`, then run:
242
+ This handoff is for the existing source of an app already built with Void and previously deployed directly to Cloudflare. Keep its `wrangler.jsonc` or `wrangler.json` for the first deploy; Void migrates it to `void.config.ts` and `void.lock.json` after linking the Worker. Then run:
241
243
 
242
244
  ```sh
243
245
  void deploy
@@ -247,20 +249,20 @@ If the project has no deployment destination, Void asks whether to link and depl
247
249
 
248
250
  The first handoff preserves resource bindings, production variables, encrypted secrets, event handlers, and existing routes and schedules. It builds the app, checks the uploaded version's bindings and handler set, and verifies readiness before activating it. Void saves `keep_vars: true` in your config so later deployments retain dashboard-only variables too. The active version must also be the latest uploaded version; activate or remove an unpublished candidate in Cloudflare before retrying so secret inheritance has an unambiguous source.
249
251
 
250
- Keep this first deployment focused on the existing site. Apart from the explicit ISR cache choice below, new resources, auth setup, runtime features, database migrations, and secret overrides stop the handoff before activation. A later code-only deploy continues to preserve dashboard-managed routes and visibility. Before adding a cron, queue consumer, workflow, or visibility change when those values exist only in the dashboard, add the current `routes`, `workers_dev`, and `preview_urls` values to the root Wrangler config. If the build fails, fix it and rerun `void deploy`; Void remembers the destination and checks the existing Worker again.
252
+ Keep this first deployment focused on the existing site. Apart from the explicit ISR cache choice below, new resources, auth setup, runtime features, database migrations, and secret overrides stop the handoff before activation. A later code-only deploy continues to preserve dashboard-managed routes and visibility. Before adding a cron, queue consumer, workflow, or visibility change when those values exist only in the dashboard, add the current `routes`, `workers_dev`, and `preview_urls` values under `cloudflare` in `void.config.ts`. If the build fails, fix it and rerun `void deploy`; Void remembers the destination and checks the existing Worker again.
251
253
 
252
- Pages with `prerender = true` (including automatically prerendered Markdown pages) also request ISR caching. When the existing Worker has no cache, Void asks whether to enable it and saves the choice as `routing.isr` in `void.json`:
254
+ Pages with `prerender = true` (including automatically prerendered Markdown pages) also request ISR caching. When the existing Worker has no cache, Void asks whether to enable it and saves the choice as `routing.isr` in `void.config.ts`:
253
255
 
254
256
  - **Yes:** provisions the KV cache and enables ISR in this deployment. The uploaded Worker must retain every existing binding and use exactly the approved cache namespace.
255
257
  - **No:** saves `routing.isr: false`. Pages render on each request, and later deployments keep ISR disabled until you change that setting.
256
258
 
257
- You can keep your page-level prerender and revalidate exports with either choice. The same saved choice applies to retries, other machines, and CI; completing the handoff does not change it. To choose ahead of time, set `routing.isr` to `true` or `false`. A non-interactive handoff with no saved choice stops with instructions to set it. Existing caches keep their namespace IDs. Commit `void.json` and any updated resource IDs in the root Cloudflare config.
259
+ You can keep your page-level prerender and revalidate exports with either choice. The same saved choice applies to retries, other machines, and CI; completing the handoff does not change it. To choose ahead of time, set `routing.isr` to `true` or `false`. A non-interactive handoff with no saved choice stops with instructions to set it. Existing caches keep their namespace IDs. Commit `void.config.ts` and `void.lock.json` when it changes.
258
260
 
259
- If linking reports other missing inferred resources, the error lists each binding and why the app needs it. Check that the root config uses the existing Worker's binding names and resource IDs, and that `inference.bindings` in `void.json` matches those names. An application KV binding explicitly named `ISR_CACHE` is still required. An existing D1 binding without checked-in migrations can keep its current `migrations_dir`, including an omitted value; linking does not provision a database or change its migration settings. Keep `.void/cloudflare-link.json` when retrying so the handoff checks remain in place.
261
+ If linking reports other missing inferred resources, the error lists each binding and why the app needs it. Check that `cloudflare` in `void.config.ts` uses the existing Worker's binding names and resource IDs, and that `inference.bindings` in `void.config.ts` matches those names. An application KV binding explicitly named `ISR_CACHE` is still required. An existing D1 binding without checked-in migrations can keep its current `migrations_dir`, including an omitted value; linking does not provision a database or change its migration settings. Keep `.void/cloudflare-link.json` when retrying so the handoff checks remain in place.
260
262
 
261
263
  Declining the initial link-and-deploy prompt leaves the project unchanged. Explicit platform choices and existing project links take precedence. In CI, select the destination with `--platform cloudflare` and provide Cloudflare credentials.
262
264
 
263
- Direct deployment uses the top-level JSON/JSONC configuration; convert a `wrangler.toml` with the same settings before linking. Named environments need a separate top-level config. If previews are disabled, include the existing production hostname in your config so Void can check the candidate through it.
265
+ Direct deployment uses the top-level `cloudflare` settings in `void.config.ts`; convert a `wrangler.toml` to JSON/JSONC before linking. Named environments need a separate Void project config. If previews are disabled, include the existing production hostname in your config so Void can check the candidate through it.
264
266
 
265
267
  ### What happens during deploy
266
268
 
@@ -276,7 +278,7 @@ Void reads your app's configuration and source, then:
276
278
 
277
279
  The secret and migration checks need the built Worker, so they happen after provisioning and building. If a check fails, resources may already exist, but Void has not applied remote D1 migrations or uploaded the application Worker.
278
280
 
279
- Resource IDs are saved in `wrangler.jsonc` for the next deploy. Void preserves comments, though it may adjust indentation when writing the file. Commit the updated config so other machines and CI can reuse the same resources. The old `--provision` flag is still accepted, but provisioning is now automatic.
281
+ Resource IDs are saved in `void.lock.json` for the next deploy. Commit the lock so other machines and CI can reuse the same resources. The old `--provision` flag is still accepted, but provisioning is now automatic.
280
282
 
281
283
  Run the first deploy from one machine at a time. The provisioning lock protects a local config file; it cannot coordinate two fresh CI runners, which could create duplicate resources.
282
284
 
@@ -284,7 +286,7 @@ Run the first deploy from one machine at a time. The provisioning lock protects
284
286
 
285
287
  Set `CLOUDFLARE_API_TOKEN` in your CI secrets. The token needs Workers Scripts: Edit and read access to bound resources, plus edit permission for each product Void needs to provision. Set `CLOUDFLARE_ACCOUNT_ID` if the token can access more than one account.
286
288
 
287
- Email setup needs a browser session from `void cloudflare login`, which carries the Email Routing and Email Sending scopes, or a `CLOUDFLARE_API_TOKEN` that also has Email Routing Edit and Email Sending Edit. A Global API Key pair is refused. In CI the email step never prompts: run `void email setup --platform cloudflare` once locally, commit `wrangler.jsonc`, then deploy with `--require-email`.
289
+ Email setup needs a browser session from `void cloudflare login`, which carries the Email Routing and Email Sending scopes, or a `CLOUDFLARE_API_TOKEN` that also has Email Routing Edit and Email Sending Edit. A Global API Key pair is refused. In CI the email step never prompts: run `void email setup --platform cloudflare` once locally, commit `void.lock.json`, then deploy with `--require-email`.
288
290
 
289
291
  When a Worker has no version preview URL, such as a Worker with Durable Objects, also set `CLOUDFLARE_WORKERS_SUBDOMAIN`. Use the account subdomain, for example `my-team` or `my-team.workers.dev`. Local deploys cache this value in ignored `.void/cloudflare.json` after Cloudflare reports a deployment URL; a fresh CI checkout has no such cache.
290
292
 
@@ -304,7 +306,7 @@ If Access blocks a version preview but allows the stable Worker hostname, Void c
304
306
 
305
307
  PostgreSQL and MySQL apps need a production `DATABASE_URL` in the deploy process environment. Void uses it for Hyperdrive provisioning and migrations, and never writes it to generated config. PostgreSQL migrations are transactional; MySQL schema changes may partially apply before an error.
306
308
 
307
- Creating a Hyperdrive config for the first time also requires `CLOUDFLARE_API_TOKEN` with Hyperdrive edit permission. Void needs the REST API to find existing configurations, and the current provisioning path can't use browser OAuth for that lookup. Alternatively, create the config in the Cloudflare dashboard and add its ID to the `hyperdrive` binding in `wrangler.jsonc`. An app with an existing Hyperdrive binding can deploy through browser login.
309
+ Creating a Hyperdrive config for the first time also requires `CLOUDFLARE_API_TOKEN` with Hyperdrive edit permission. Void needs the REST API to find existing configurations, and the current provisioning path can't use browser OAuth for that lookup. Alternatively, create the config in the Cloudflare dashboard and add its ID to the `cloudflare.hyperdrive` binding in `void.config.ts`. An app with an existing Hyperdrive binding can deploy through browser login.
308
310
 
309
311
  For auth-enabled apps, run `void db generate` and commit the migrations. Void includes the production Better Auth schema, including renamed tables and plugin tables, and checks it against your migration history during deploy. D1 also gets an in-memory schema check before remote migration. A mismatch stops deployment and asks you to regenerate the SQL.
310
312
 
@@ -339,7 +341,7 @@ Void supports Worker apps, static sites, SPAs, known SSGs, `--dir` deploys, and
339
341
 
340
342
  Static sites use a small Worker in front of Workers Assets to handle redirects, rewrites, fallbacks, and headers. Hybrid and SSR apps keep their application Worker. A page that opts out of prerendering, a dynamic page without `getPrerenderPaths()`, or another runtime feature keeps the app on a Worker even with `output: "static"`.
341
343
 
342
- Native Void applications apply `void.json` routing rules in their Worker.
344
+ Native Void applications apply `void.config.ts` routing rules in their Worker.
343
345
  Framework-owned Workers do not yet support those Void redirects, rewrites,
344
346
  fallbacks, or headers on the direct target. The CLI rejects such configuration
345
347
  before provisioning or building; configure the rules in the framework or its
@@ -348,15 +350,13 @@ Worker instead. This restriction does not change an explicit asset policy for
348
350
 
349
351
  Worker apps support D1, KV, R2, Queues, typed state, PostgreSQL and MySQL through Hyperdrive, auth, WebSockets, AI, cron jobs, and ISR. The main limits are:
350
352
 
351
- - **Sandbox needs Workers Paid and Docker.** Importing `void/sandbox` or enabling `sandbox` in `void.json` adds a Container application. Void checks access before provisioning or building. [Enable Workers Paid](https://dash.cloudflare.com/?to=/:account/workers/plans) and sign in again if needed. API tokens need Account / Containers: Edit and Account / Cloudchamber: Edit. See [Containers pricing](https://developers.cloudflare.com/containers/pricing/). Apps without Sandbox skip this check and remain compatible with Workers Free within its quotas.
353
+ - **Sandbox needs Workers Paid and Docker.** Importing `void/sandbox` or enabling `sandbox` in `void.config.ts` adds a Container application. Void checks access before provisioning or building. [Enable Workers Paid](https://dash.cloudflare.com/?to=/:account/workers/plans) and sign in again if needed. API tokens need Account / Containers: Edit and Account / Cloudchamber: Edit. See [Containers pricing](https://developers.cloudflare.com/containers/pricing/). Apps without Sandbox skip this check and remain compatible with Workers Free within its quotas.
352
354
  - **Worker apps need a fresh build.** `--skip-build` works for existing static, SPA, and SSG output. Worker validation needs the current build's vars and auth schema.
353
- - **Named Cloudflare environments aren't supported.** Direct commands use the top-level root config and reject `CLOUDFLARE_ENV`, `CLOUDFLARE_VITE_WRANGLER_CONFIG_PATH`, and project-local name overrides. Use a separate root config per deployment target.
355
+ - **Named Cloudflare environments aren't supported.** Direct commands use the top-level `cloudflare` settings and reject `CLOUDFLARE_ENV`, `CLOUDFLARE_VITE_WRANGLER_CONFIG_PATH`, and project-local name overrides. Use a separate Void project config per deployment target.
354
356
  - **Node.js, Bun, and Deno use a different deployment path.** See their [integration guide](./nodejs-bun-deno.md).
355
- - **Email is set up on the first deploy, on a zone you own.** Put `email.from` in `void.json`; the deploy reads your account, prints a checklist of what it would change, and asks once. See [Your own Cloudflare account](../guide/email.md#your-own-cloudflare-account). Outside Void's reach: `email/_default.ts` and dynamic local parts (`email/[user].ts`) need a catch-all, which exists only on a zone apex, so on a mail subdomain they get no rule; a mail domain that already has non-Cloudflare MX records is refused, never routed over; `sendEmail()` to arbitrary recipients needs Workers Paid (Email Sending onboarding), otherwise verified destinations only; Void owns the top-level `addresses` array in `wrangler.jsonc`, so hand-written entries there skip the email step; and `void email usage`, `logs`, `allow`, and `destinations` are platform-only.
357
+ - **Email is set up on the first deploy, on a zone you own.** Put `email.from` in `void.config.ts`; the deploy reads your account, prints a checklist of what it would change, and asks once. See [Your own Cloudflare account](../guide/email.md#your-own-cloudflare-account). Outside Void's reach: `email/_default.ts` and dynamic local parts (`email/[user].ts`) need a catch-all, which exists only on a zone apex, so on a mail subdomain they get no rule; a mail domain that already has non-Cloudflare MX records is refused, never routed over; `sendEmail()` to arbitrary recipients needs Workers Paid (Email Sending onboarding), otherwise verified destinations only; Void owns the top-level `addresses` array in the generated Cloudflare config, so hand-written `cloudflare.addresses` entries skip the email step; and `void email usage`, `logs`, `allow`, and `destinations` are platform-only.
356
358
 
357
- WebSocket routes and typed state use SQLite-backed Durable Objects. Commit the bindings and `new_sqlite_classes` migration history in `wrangler.jsonc`; don't delete or reorder deployed migration steps. Older hosted classes using `new_classes` keep their existing storage.
358
-
359
- Bare `vite build && wrangler deploy` does not provision schema-declared secrets. Use `wrangler secret bulk` / `wrangler secret put` and list every inherited name under `secrets.required` yourself.
359
+ WebSocket routes and typed state use SQLite-backed Durable Objects. Commit `void.lock.json` when Void adds bindings or `new_sqlite_classes` migration history; don't delete or reorder deployed migration steps. Older hosted classes using `new_classes` keep their existing storage.
360
360
 
361
361
  ISR uses the shared cache protocol. Entries are scoped to a deployment and hostname, and `routing.revalidateQueryAllowlist` adds bounded query variants. `revalidate()` purges matching entries and variants from KV and the local edge cache. See [ISR](#isr-self-host) below for cache behavior across regions.
362
362
 
@@ -378,22 +378,23 @@ These checks detect changes to the deployment target or uploader, but they don't
378
378
 
379
379
  ### Local development
380
380
 
381
- `pnpm dev` continues to work as before -- Miniflare creates local instances of all bindings regardless of the IDs in your `wrangler.jsonc`. Your real resource IDs are only used during direct Cloudflare deployment.
381
+ `pnpm dev` continues to work as before -- Miniflare creates local instances of all bindings regardless of the IDs in `void.config.ts`. Your real resource IDs are only used during direct Cloudflare deployment.
382
382
 
383
383
  ### AI on your Cloudflare account {#ai-self-host}
384
384
 
385
385
  `void/ai` works on your own Cloudflare account, along two paths:
386
386
 
387
- - **Workers AI** (`ai.run`, `ai.stream`, `ai.image`) works out of the box. When your app imports `void/ai`, `vite build` infers that you need AI and adds a Workers AI binding (`env.AI`) to the generated `wrangler.json` automatically -- you do **not** add it to `wrangler.jsonc`. Set `inference.bindings.ai` to a string to use a custom name.
388
- - **Provider models** (`ai.provider("openai").fetch(...)`) route through _your own_ Cloudflare AI Gateway. Set its id in `void.json` and add the provider's API key as a Worker secret.
387
+ - **Workers AI** (`ai.run`, `ai.stream`, `ai.image`) works out of the box. When your app imports `void/ai`, `vite build` infers that you need AI and adds a Workers AI binding (`env.AI`) to the generated build config automatically. Set `inference.bindings.ai` to a string to use a custom name.
388
+ - **Provider models** (`ai.provider("openai").fetch(...)`) route through _your own_ Cloudflare AI Gateway. Set its id in `void.config.ts` and add the provider's API key as a Worker secret.
389
389
 
390
- ```jsonc
391
- // void.json
392
- {
393
- "ai": {
394
- "gateway": "my-gateway", // an AI Gateway in YOUR Cloudflare account
390
+ ```ts
391
+ import { defineConfig } from 'void/config';
392
+
393
+ export default defineConfig({
394
+ ai: {
395
+ gateway: 'my-gateway', // an AI Gateway in your Cloudflare account
395
396
  },
396
- }
397
+ });
397
398
  ```
398
399
 
399
400
  ```bash
@@ -408,7 +409,7 @@ import { ai } from 'void/ai';
408
409
 
409
410
  export const POST = defineHandler(async (c) => {
410
411
  // Workers AI -- uses the inferred or configured AI binding directly
411
- const summary = await ai.run('@cf/meta/llama-3.1-8b-instruct', {
412
+ const summary = await ai.run('@cf/meta/llama-3.3-70b-instruct-fp8-fast', {
412
413
  prompt: 'Summarize the changelog.',
413
414
  });
414
415
 
@@ -428,22 +429,23 @@ Set `ai.gateway` before calling `ai.provider().fetch()`; otherwise it returns `5
428
429
  Notes:
429
430
 
430
431
  - **Account-owned usage.** Direct deployments use your own [Cloudflare AI Gateway analytics](https://developers.cloudflare.com/ai-gateway/). A team platform meters requests through its shared proxy; those usage records do not automatically bill application developers.
431
- - **Custom AI binding names are supported.** Configure `"inference": { "bindings": { "ai": "MY_AI" } }`, or declare the custom `ai.binding` in your root Wrangler config; the generated worker records the resolved name for `void/ai` automatically.
432
+ - **Custom AI binding names are supported.** Set `inference.bindings.ai` to `MY_AI`, or declare `cloudflare.ai.binding` in `void.config.ts`; the generated worker records the resolved name for `void/ai` automatically.
432
433
  - **Workers AI runs remotely during development.** After `void connect --platform cloudflare`, an app importing `void/ai` uses your account's remote AI binding with your Cloudflare login or API token. Development and preview calls consume that account's allowance. Apps without AI imports add no AI binding or authentication probe.
433
434
 
434
435
  ### ISR on your Cloudflare account {#isr-self-host}
435
436
 
436
- [Revalidation (ISR)](../guide/edge/revalidation.md) works self-hosted. `void deploy --platform cloudflare` automatically creates or reuses the cache KV namespace and persists its `ISR_CACHE` binding in `wrangler.jsonc`, just like the other inferred resources.
437
+ [Revalidation (ISR)](../guide/edge/revalidation.md) works self-hosted. `void deploy --platform cloudflare` automatically creates or reuses the cache KV namespace and records its `ISR_CACHE` binding in `void.lock.json`, just like the other inferred resources.
437
438
 
438
- Configure revalidation exactly as on the platform -- globally or per-path in `void.json`:
439
+ Configure revalidation exactly as on the platform -- globally or per-path in `void.config.ts`:
439
440
 
440
- ```jsonc
441
- // void.json
442
- {
443
- "routing": {
444
- "revalidate": { "/blog/*": 3600, "*": 60 },
441
+ ```ts
442
+ import { defineConfig } from 'void/config';
443
+
444
+ export default defineConfig({
445
+ routing: {
446
+ revalidate: { '/blog/*': 3600, '*': 60 },
445
447
  },
446
- }
448
+ });
447
449
  ```
448
450
 
449
451
  ...or per page with an exported `revalidate` literal in a `.server.ts` companion (Pages mode):
@@ -40,6 +40,7 @@ export default defineConfig({
40
40
  ssr: true,
41
41
  nitro: {
42
42
  preset: 'cloudflare-module',
43
+ cloudflareDev: { configPath: './.void-wrangler.jsonc' },
43
44
  modules: ['nitro-cloudflare-dev'],
44
45
  alias: {
45
46
  // Nitro has its own bundler that doesn't use Vite aliases.
@@ -53,16 +54,20 @@ export default defineConfig({
53
54
  });
54
55
  ```
55
56
 
56
- ### 4. Create `wrangler.jsonc`
57
+ ### 4. Create `void.config.ts`
57
58
 
58
- `voidPlugin()` auto-syncs inferred bindings into this file on dev startup:
59
+ Void generates the Cloudflare config used by Analog's development runtime:
59
60
 
60
- ```jsonc
61
- {
62
- "name": "my-app",
63
- "compatibility_date": "2026-02-24",
64
- "compatibility_flags": ["nodejs_compat", "nodejs_als"],
65
- }
61
+ ```ts
62
+ import { defineConfig } from 'void/config';
63
+
64
+ export default defineConfig({
65
+ cloudflare: {
66
+ name: 'my-app',
67
+ compatibility_date: '2026-02-24',
68
+ compatibility_flags: ['nodejs_compat', 'nodejs_als'],
69
+ },
70
+ });
66
71
  ```
67
72
 
68
73
  `nodejs_compat` is required for Nitro's Cloudflare runtime. `nodejs_als` is required for `void/*` runtime helpers (e.g. `void/db`, `void/kv`).
@@ -127,7 +132,7 @@ import { eventHandler } from 'h3';
127
132
  import { ai } from 'void/ai';
128
133
 
129
134
  export default eventHandler(async () => {
130
- return ai.run('@cf/meta/llama-3.1-8b-instruct', {
135
+ return ai.run('@cf/meta/llama-3.3-70b-instruct-fp8-fast', {
131
136
  prompt: 'Summarize the latest news',
132
137
  });
133
138
  });
@@ -35,23 +35,27 @@ import cloudflare from '@astrojs/cloudflare';
35
35
  import { voidPlugin } from 'void';
36
36
 
37
37
  export default defineConfig({
38
- adapter: cloudflare(),
38
+ adapter: cloudflare({ configPath: './.void-wrangler.jsonc' }),
39
39
  vite: { plugins: [voidPlugin()] },
40
40
  });
41
41
  ```
42
42
 
43
43
  By default, Astro's Cloudflare runtime and `voidPlugin()` migrations share local state at `.wrangler/state/v3`, so no extra persistence configuration is required.
44
44
 
45
- ### 4. Create `wrangler.jsonc`
45
+ ### 4. Create `void.config.ts`
46
46
 
47
- `voidPlugin()` auto-syncs inferred bindings into this file on dev startup:
47
+ Void uses this config for the Cloudflare adapter during development and deployment:
48
48
 
49
- ```jsonc
50
- {
51
- "name": "my-app",
52
- "compatibility_date": "2026-02-24",
53
- "compatibility_flags": ["nodejs_als"],
54
- }
49
+ ```ts
50
+ import { defineConfig } from 'void/config';
51
+
52
+ export default defineConfig({
53
+ cloudflare: {
54
+ name: 'my-app',
55
+ compatibility_date: '2026-02-24',
56
+ compatibility_flags: ['nodejs_als'],
57
+ },
58
+ });
55
59
  ```
56
60
 
57
61
  `nodejs_als` is required for `void/*` runtime helpers (for example `void/db`, `void/kv`) in Astro.
@@ -126,7 +130,7 @@ import type { APIRoute } from 'astro';
126
130
  import { ai } from 'void/ai';
127
131
 
128
132
  export const POST: APIRoute = async () => {
129
- const result = await ai.run('@cf/meta/llama-3.1-8b-instruct', {
133
+ const result = await ai.run('@cf/meta/llama-3.3-70b-instruct-fp8-fast', {
130
134
  prompt: 'Summarize the latest news',
131
135
  });
132
136
  return Response.json(result);
@@ -32,6 +32,7 @@ import { voidPlugin } from 'void';
32
32
  export default defineNuxtConfig({
33
33
  nitro: {
34
34
  preset: 'cloudflare-module',
35
+ cloudflareDev: { configPath: './.void-wrangler.jsonc' },
35
36
  alias: {
36
37
  // Nitro has its own bundler that doesn't use Vite aliases.
37
38
  // Duplicate @schema here so Nitro can resolve it.
@@ -44,16 +45,20 @@ export default defineNuxtConfig({
44
45
 
45
46
  By default, Nuxt's Cloudflare development runtime and `voidPlugin()` migrations share local state at `.wrangler/state/v3`, so no extra persistence configuration is required.
46
47
 
47
- ### 4. Create `wrangler.jsonc`
48
+ ### 4. Create `void.config.ts`
48
49
 
49
- `voidPlugin()` auto-syncs inferred bindings into this file on dev startup:
50
+ Void generates the Cloudflare config used by Nuxt's development runtime:
50
51
 
51
- ```jsonc
52
- {
53
- "name": "my-app",
54
- "compatibility_date": "2026-02-24",
55
- "compatibility_flags": ["nodejs_compat", "nodejs_als"],
56
- }
52
+ ```ts
53
+ import { defineConfig } from 'void/config';
54
+
55
+ export default defineConfig({
56
+ cloudflare: {
57
+ name: 'my-app',
58
+ compatibility_date: '2026-02-24',
59
+ compatibility_flags: ['nodejs_compat', 'nodejs_als'],
60
+ },
61
+ });
57
62
  ```
58
63
 
59
64
  ### 5. Deploy
@@ -111,7 +116,7 @@ export default defineEventHandler(async () => {
111
116
  import { ai } from 'void/ai';
112
117
 
113
118
  export default defineEventHandler(async () => {
114
- return ai.run('@cf/meta/llama-3.1-8b-instruct', {
119
+ return ai.run('@cf/meta/llama-3.3-70b-instruct-fp8-fast', {
115
120
  prompt: 'Summarize the latest news',
116
121
  });
117
122
  });