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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "void",
3
- "version": "0.20.2",
3
+ "version": "0.21.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/voidzero-dev/void.git",
@@ -50,6 +50,11 @@
50
50
  "require": "./dist/index.mjs"
51
51
  },
52
52
  "./schema.json": "./schema.json",
53
+ "./config": {
54
+ "types": "./dist/config-entry.d.mts",
55
+ "import": "./dist/config-entry.mjs",
56
+ "require": "./dist/config-entry.mjs"
57
+ },
53
58
  "./database-provider": {
54
59
  "types": "./dist/database-provider.d.mts",
55
60
  "import": "./dist/database-provider.mjs",
@@ -314,18 +319,22 @@
314
319
  }
315
320
  },
316
321
  "dependencies": {
322
+ "@cloudflare/build-output-utils": "0.8.2",
323
+ "@cloudflare/config": "0.20.0",
317
324
  "@cloudflare/sandbox": "^0.12.9",
318
325
  "@cloudflare/vite-plugin": "1.54.7",
319
326
  "@cloudflare/workers-types": "^4.20260702.1",
320
327
  "@napi-rs/keyring": "2.0.0",
321
- "@void/deploy-cloudflare": "0.20.2",
322
- "@void/deploy-core": "0.20.2",
323
- "@void/edge": "0.20.2",
324
- "@void/isr": "0.20.2",
325
- "@void/platform": "0.20.2",
328
+ "@void/deploy-cloudflare": "0.21.0",
329
+ "@void/deploy-core": "0.21.0",
330
+ "@void/edge": "0.21.0",
331
+ "@void/isr": "0.21.0",
332
+ "@void/platform": "0.21.0",
333
+ "acorn": "^8.15.0",
326
334
  "better-auth": "^1.7.3",
327
335
  "better-sqlite3": "^13.0.3",
328
336
  "blake3-jit": "^1.1.0",
337
+ "cf": "1.0.0-beta.5",
329
338
  "drizzle-arktype": "^0.1.3",
330
339
  "drizzle-kit": "^0.31.10",
331
340
  "drizzle-orm": "^0.45.2",
@@ -335,13 +344,15 @@
335
344
  "es-module-lexer": "^3.0.2",
336
345
  "hono": "^4.13.7",
337
346
  "ignore": "^7.0.9",
347
+ "jiti": "^2.7.0",
338
348
  "jsonc-parser": "3.3.1",
349
+ "miniflare": "5.20260926.0-alpha",
339
350
  "minimatch": "^10.2.6",
340
351
  "mysql2": "3.24.4",
341
352
  "pg": "8.23.0",
342
353
  "postal-mime": "^2.7.4",
343
354
  "proper-lockfile": "^4.1.2",
344
- "wrangler": "4.131.0"
355
+ "undici": "7.29.0"
345
356
  },
346
357
  "devDependencies": {
347
358
  "@clack/core": "1.5.0",
@@ -368,7 +379,7 @@
368
379
  "zod": "^4.6.1"
369
380
  },
370
381
  "peerDependencies": {
371
- "@void/md": "0.20.2",
382
+ "@void/md": "0.21.0",
372
383
  "arktype": ">=2.0.0",
373
384
  "valibot": ">=1.0.0-beta.7",
374
385
  "vite": "^8.0.0",
@@ -23,11 +23,11 @@ read permission; `void platform install --plan` verifies coverage. Use the
23
23
  self-hosted platform guide for certificate setup rather than enabling a paid
24
24
  product without an explicit request.
25
25
 
26
- For first-time platform setup, follow `docs/guide/self-hosted-platform.md` in order and introduce credentials when the user reaches that step. Recommend a domain; offer explicit `void platform install --workers-dev` for testing before one is ready. PostgreSQL, credentials for the selected login methods, runtime/R2 credentials, and saved signing/encryption keys are required. GitHub is the default and is optional. `--auth-config` accepts nonsecret provider configuration with environment secret references; `--plan` does not read those secrets. Configurable installations finish first-administrator setup using a one-time code and browser identity confirmation. Domain-free installation skips zone/DNS/certificate operations and can use browser login. `void platform domain set <domain>` later performs resumable DNS/HTTPS setup while preserving existing test URLs and the API origin. The command checks the deployed runtime token's cache-purge permission for the new zone; it does not ask users to retrieve that token. Prefer interactive prompts for secrets and keep CI variables in the CI workflow. Void creates the platform infrastructure and database tables.
26
+ For first-time platform setup, follow the installation pages linked from `docs/guide/self-hosted-platform.md` in order and introduce credentials when the user reaches that step. Recommend a domain; offer explicit `void platform install --workers-dev` for testing before one is ready. PostgreSQL, credentials for the selected login methods, runtime/R2 credentials, and saved signing/encryption keys are required. GitHub is the default and is optional. `--auth-config` accepts nonsecret provider configuration with environment secret references; `--plan` does not read those secrets. Configurable installations finish first-administrator setup using a one-time code and browser identity confirmation. Domain-free installation skips zone/DNS/certificate operations and can use browser login. `void platform domain set <domain>` later performs resumable DNS/HTTPS setup while preserving existing test URLs and the API origin. The command checks the deployed runtime token's cache-purge permission for the new zone; it does not ask users to retrieve that token. Interactive installation asks whether Void should create Hyperdrive or use a separately managed one; if the latter is missing, it gives setup instructions and stops before provisioning. It still prompts for the owner PostgreSQL URL. Prefer interactive prompts for secrets and keep CI variables in the CI workflow. Void creates the platform infrastructure and database tables.
27
27
 
28
- For an existing Cloudflare site, run `void deploy` with its root `wrangler.jsonc` or `wrangler.json`. An unlinked project gets a prompt to link and deploy using the existing Worker and resources. Accepting verifies and saves the destination, then continues deployment. Keep new application resources, migrations, auth setup, and secret changes separate from this first handoff; ISR has its own explicit cache choice. The active Worker Version must be the latest upload so inherited secrets have an unambiguous source. Failed builds retain the link for retry. Read `docs/integrations/cloudflare.md` for the supported configuration and rollback behavior.
28
+ For an existing Cloudflare site, run `void deploy` with its root `wrangler.jsonc` or `wrangler.json`. An unlinked project gets a prompt to link and deploy using the existing Worker and resources. Accepting verifies and saves the destination, migrates the root config to `void.config.ts` and `void.lock.json`, then continues deployment. Keep new application resources, migrations, auth setup, and secret changes separate from this first handoff; ISR has its own explicit cache choice. The active Worker Version must be the latest upload so inherited secrets have an unambiguous source. Failed builds retain the link for retry. Read `docs/integrations/cloudflare.md` for the supported configuration and rollback behavior.
29
29
 
30
- When linking reports missing inferred resources, check the listed bindings and inference reasons against the existing Worker and `void.json`; preserve `.void/cloudflare-link.json` for retries. For prerendered/revalidated sites without a cache, migration saves an explicit `routing.isr` choice in `void.json`. True provisions the cache during this deployment; false keeps ISR disabled on retries and later deployments until changed. Keep page-level exports with either choice. CI must configure the boolean before resuming a migration with no saved choice. An application KV binding explicitly named `ISR_CACHE` is still required. Existing D1 bindings without checked-in migrations retain their local migration settings during handoff.
30
+ When linking reports missing inferred resources, check the listed bindings and inference reasons against the existing Worker and `void.config.ts`; preserve `.void/cloudflare-link.json` for retries. For prerendered/revalidated sites without a cache, migration saves an explicit `routing.isr` choice in `void.config.ts`. True provisions the cache during this deployment; false keeps ISR disabled on retries and later deployments until changed. Keep page-level exports with either choice. CI must configure the boolean before resuming a migration with no saved choice. An application KV binding explicitly named `ISR_CACHE` is still required. Existing D1 bindings without checked-in migrations retain their local migration settings during handoff.
31
31
 
32
32
  For Cloudflare upload failures, use the detailed error message printed by the CLI and saved in the deploy log. A numeric error code alone may not identify the cause.
33
33
 
@@ -91,7 +91,9 @@ Cloudflare browser login does not grant AI Gateway access. A platform installati
91
91
 
92
92
  Use `--runtime <directory>` on platform install, upgrade, repair, enable, or rollback when deploying a locally built `@void/platform` runtime. The directory must contain the generated integrity manifest, Worker artifacts, and migration tree. Build it with `vp run --filter @void/platform build`; Git source revisions are detected automatically, with `-dirty` for uncommitted changes. `VOID_PLATFORM_SOURCE_REVISION` is an optional override. Do not treat this as a safety bypass: custom and packaged runtimes follow the same verification and rollback path.
93
93
 
94
- For self-hosted platform installation, require a dedicated empty PostgreSQL database. Interactive lifecycle commands use Cloudflare browser OAuth with keyring storage. Wrangler OAuth has Zone Read, so a plan that creates a zone or DNS record requires a scoped `CLOUDFLARE_API_TOKEN` with Account → Zone → Edit and/or Zone → DNS → Edit; finish Workers onboarding and choose a workers.dev subdomain for a fresh Cloudflare account. The installed platform uses a separate `VOID_PLATFORM_RUNTIME_CLOUDFLARE_API_TOKEN`. Its core permissions include Hyperdrive: Write at account scope and Cache Purge: Purge on the application zone; SSL and Certificates: Edit is needed only when a custom runtime enables custom project domains. The installer preflights account and Hyperdrive access and safely verifies Cache Purge for an existing zone with a unique nonexistent URL. Fresh installs require unique per-installation values from the operator's secret manager: `VOID_PLATFORM_JWT_SECRET` with at least 32 random bytes and `VOID_PLATFORM_PROJECT_SECRET_KEY` as canonical base64 for 32 random bytes. Never let a local checkpoint or ephemeral CI runner be their only custodian. Enabling email generates a separate signing key in encrypted recovery state; supply `VOID_PLATFORM_EMAIL_SIGNING_SECRET` from the secret manager for headless installs without persistent recovery files. The installer transactionally claims the database for one installation, pins that URL after a successful claim, never removes the claim during uninstall, and uses it for a cross-host lifecycle lock plus a secret-free authoritative lifecycle manifest. Local recovery checkpoints are AES-256-GCM encrypted with an OS-keychain key; never place platform secrets in plaintext files. After discovery on a new machine, provide `VOID_PLATFORM_DATABASE_URL`. For email-enabled installations without encrypted recovery state, also restore the original `VOID_PLATFORM_EMAIL_SIGNING_SECRET`; recreating only the email gateway needs this key, not JWT or runtime credentials. Normal upgrades preserve other deployed Worker secrets; restore the original runtime, GitHub, R2, JWT, and project-encryption values when recreating the API or proxy as documented. Managed platform Sandbox is paused for removal: preview `void platform system sandbox-drain --plan`, follow each returned `nextCursor` with `--cursor '<value>'` to inspect bounded pages, then apply with `--yes` and rerun until the DB-backed response reports `complete: true`; never delete an unverified app by name. The installer trusts only DB-backed sandbox-drain probe protocol v1. Before it accepts an empty inventory, the database admission barrier makes older deployment inserts finish and become visible or rejects them after the protocol floor is armed. Lifecycle redeploys preserve unmanaged Worker routes and custom domains in both the new trigger state and rollback snapshot. They stop before migrations or uploads when live Hyperdrive origin metadata differs from the pinned database. Platform upgrade SQL is forward-only: packaged hashes and the live Drizzle prefix must match, pending migrations require an exact source-version/schema rollback edge, and the old version remains authoritative until target health succeeds. Use `void platform rollback --runtime <earlier>` only when the installed runtime declares the exact earlier version/schema compatible; pass `--from-runtime` for the exact current custom artifact. Rollback preserves the forward database schema and cannot lower a database-required safety protocol. Safe uninstall retains Worker routes, custom domains, and R2 for explicit manual cleanup because Cloudflare cannot condition their deletion on an immutable generation.
94
+ For self-hosted platform installation, require a dedicated empty PostgreSQL database. Interactive lifecycle commands use Cloudflare browser OAuth with keyring storage. Wrangler OAuth has Zone Read, so a plan that creates a zone or DNS record requires a scoped `CLOUDFLARE_API_TOKEN` with Account → Zone → Edit and/or Zone → DNS → Edit; finish Workers onboarding and choose a workers.dev subdomain for a fresh Cloudflare account. The installed platform uses a separate `VOID_PLATFORM_RUNTIME_CLOUDFLARE_API_TOKEN`. Its core permissions include Hyperdrive: Write at account scope and Cache Purge: Purge on the application zone; SSL and Certificates: Edit is needed only when a custom runtime enables custom project domains. Managed Sandbox apps additionally require Workers Paid plus Account → Containers → Edit and Account → Cloudchamber → Edit on that runtime token; these are checked on the first Sandbox application deploy, not during platform install or upgrade. The installer preflights account and Hyperdrive access and safely verifies Cache Purge for an existing zone with a unique nonexistent URL. Fresh installs require unique per-installation values from the operator's secret manager: `VOID_PLATFORM_JWT_SECRET` with at least 32 random bytes and `VOID_PLATFORM_PROJECT_SECRET_KEY` as canonical base64 for 32 random bytes. Never let a local checkpoint or ephemeral CI runner be their only custodian. Enabling email generates a separate signing key in encrypted recovery state; supply `VOID_PLATFORM_EMAIL_SIGNING_SECRET` from the secret manager for headless installs without persistent recovery files. The installer transactionally claims the database for one installation, pins that URL after a successful claim, never removes the claim during uninstall, and uses it for a cross-host lifecycle lock plus a secret-free authoritative lifecycle manifest. Local recovery checkpoints are AES-256-GCM encrypted with an OS-keychain key; never place platform secrets in plaintext files. After discovery on a new machine, provide `VOID_PLATFORM_DATABASE_URL`. For email-enabled installations without encrypted recovery state, also restore the original `VOID_PLATFORM_EMAIL_SIGNING_SECRET`; recreating only the email gateway needs this key, not JWT or runtime credentials. Normal upgrades preserve other deployed Worker secrets; restore the original runtime, GitHub, R2, JWT, and project-encryption values when recreating the API or proxy as documented. Upgrades enable managed Sandboxes automatically. An upgrade from the tenant-owned legacy may still require `void platform system sandbox-drain`: preview with `--plan`, follow each `nextCursor`, then apply with `--yes` until the DB-backed response reports `complete: true`; never delete an unverified app by name. The installer trusts only DB-backed sandbox-drain probe protocol v1. Before it accepts an empty inventory, the database admission barrier makes older deployment inserts finish and become visible or rejects them after the protocol floor is armed. Lifecycle redeploys preserve unmanaged Worker routes and custom domains in both the new trigger state and rollback snapshot. They stop before migrations or uploads when live Hyperdrive origin metadata differs from the pinned database. Platform upgrade SQL is forward-only: packaged hashes and the live Drizzle prefix must match, pending migrations require an exact source-version/schema rollback edge, and the old version remains authoritative until target health succeeds. Use `void platform rollback --runtime <earlier>` only when the installed runtime declares the exact earlier version/schema compatible; pass `--from-runtime` for the exact current custom artifact. Rollback preserves the forward database schema and cannot lower a database-required safety protocol. Safe uninstall retains Worker routes, custom domains, and R2 for explicit manual cleanup because Cloudflare cannot condition their deletion on an immutable generation.
95
+
96
+ For an organization-managed Hyperdrive, set `VOID_PLATFORM_HYPERDRIVE_ID`, `VOID_PLATFORM_HYPERDRIVE_ORIGIN_HOST`, and `VOID_PLATFORM_HYPERDRIVE_ORIGIN_USER` together before installation. Use `VOID_PLATFORM_DATABASE_URL` for a separate owner connection that runs migrations; the Hyperdrive must be named `void-<installation-name>-database` and have SQL result caching disabled. See `docs/guide/platform/installation/prerequisites.md`.
95
97
 
96
98
  For self-hosted recovery, `VOID_PLATFORM_PROJECT_SECRET_KEY` restores an original `v1` project-secret keyring. After rotation, restore every retained version with `VOID_PLATFORM_PROJECT_SECRET_KEYS_JSON` and its active entry with `VOID_PLATFORM_PROJECT_SECRET_ACTIVE_KEY_VERSION`. These inputs restore a missing API Worker and never replace the live keyring of an existing Worker. Inject them from a secret manager without logging them or writing plaintext files.
97
99
 
@@ -107,7 +109,7 @@ If invoked without a concrete task, do a brief app status check and report:
107
109
  2. Backend feature usage (`routes/`, `pages/`, `middleware/`, `migrations/`, `crons/`, `queues/`, SSR entries).
108
110
  3. Runtime signals (`void/db`, `void/kv`, `void/storage`, queue usage).
109
111
  4. Auth signals (`void/auth`, `auth` client imports, OAuth env vars).
110
- 5. Deployment platform and optional Void project linkage (`.void/project.json`), plus config readiness (`void.json`, Cloudflare `account_id`, tsconfig extends).
112
+ 5. Deployment platform and optional Void project linkage (`.void/project.json`), plus config readiness (`void.config.ts`, Cloudflare `account_id`, tsconfig extends).
111
113
  6. Optional health checks (`void auth whoami`, `void db status` when relevant).
112
114
 
113
115
  Then ask what to do next.
@@ -21,7 +21,7 @@ import { ai } from 'void/ai';
21
21
  export const POST = defineHandler(async (c) => {
22
22
  const { prompt } = await c.req.json();
23
23
 
24
- const result = await ai.run('@cf/meta/llama-3.1-8b-instruct', {
24
+ const result = await ai.run('@cf/meta/llama-3.3-70b-instruct-fp8-fast', {
25
25
  messages: [{ role: 'user', content: prompt }],
26
26
  });
27
27
 
@@ -29,7 +29,7 @@ export const POST = defineHandler(async (c) => {
29
29
  });
30
30
  ```
31
31
 
32
- You can use any model available through Cloudflare's AI binding, including Workers AI models such as `@cf/meta/llama-3.1-8b-instruct` and Cloudflare Gateway models such as `google/gemini-2.5-flash` or `openai/gpt-4.1-mini`. The input object must match the selected Cloudflare model's schema. Models that return binary data, such as generated images, are returned as a `Blob` from `ai.run()`.
32
+ You can use any model available through Cloudflare's AI binding, including Workers AI models such as `@cf/meta/llama-3.3-70b-instruct-fp8-fast` and Cloudflare Gateway models such as `google/gemini-2.5-flash` or `openai/gpt-4.1-mini`. The input object must match the selected Cloudflare model's schema. Models that return binary data, such as generated images, are returned as a `Blob` from `ai.run()`.
33
33
 
34
34
  ## Streaming
35
35
 
@@ -42,7 +42,7 @@ import { ai } from 'void/ai';
42
42
  export const POST = defineHandler(async (c) => {
43
43
  const { prompt } = await c.req.json();
44
44
 
45
- return ai.stream('@cf/meta/llama-3.1-8b-instruct', {
45
+ return ai.stream('@cf/meta/llama-3.3-70b-instruct-fp8-fast', {
46
46
  messages: [{ role: 'user', content: prompt }],
47
47
  });
48
48
  });
@@ -10,7 +10,7 @@ Void supports three types of apps:
10
10
  2. **Meta frameworks:** [TanStack Start](https://tanstack.com/start/latest), [React Router](https://reactrouter.com/), [SvelteKit](https://svelte.dev/docs/kit), [Nuxt](https://nuxt.com/), and [Astro](https://astro.build/)
11
11
  3. **Static sites:** SPAs, sites built with tools like [VitePress](https://vitepress.dev/), or any directory of static files
12
12
 
13
- The type is auto-detected from your project structure, or you can set it explicitly in [`void.json`](../reference/config.md).
13
+ The type is auto-detected from your project structure, or you can set it explicitly in [`void.config.ts`](../reference/config.md).
14
14
 
15
15
  ## Void Apps
16
16
 
@@ -79,14 +79,15 @@ If you add API routes to a static site generator, tell Void whether to deploy th
79
79
 
80
80
  To deploy both, set `appType` to `"void"` and build the static site before the Void app:
81
81
 
82
- ```json
83
- // void.json
84
- {
85
- "inference": {
86
- "appType": "void",
87
- "build": "vitepress build && vite build"
88
- }
89
- }
82
+ ```ts
83
+ import { defineConfig } from 'void/config';
84
+
85
+ export default defineConfig({
86
+ inference: {
87
+ appType: 'void',
88
+ build: 'vitepress build && vite build',
89
+ },
90
+ });
90
91
  ```
91
92
 
92
93
  ```ts
@@ -117,7 +118,7 @@ To deploy only the static output, set:
117
118
 
118
119
  ## Auto-Detection
119
120
 
120
- When running `void deploy` and no `inference.appType` is set in `void.json`, the detection logic runs in this order:
121
+ When running `void deploy` and no `inference.appType` is set in `void.config.ts`, the detection logic runs in this order:
121
122
 
122
123
  | Priority | Condition | Type |
123
124
  | -------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
@@ -131,7 +132,7 @@ When running `void deploy` and no `inference.appType` is set in `void.json`, the
131
132
 
132
133
  ## Explicit Configuration
133
134
 
134
- To lock the app type and skip auto-detection, set `inference.appType` in [`void.json`](../reference/config.md):
135
+ To lock the app type and skip auto-detection, set `inference.appType` in [`void.config.ts`](../reference/config.md):
135
136
 
136
137
  ```json
137
138
  {
@@ -14,7 +14,7 @@ Void configures [Better Auth](https://www.better-auth.com/) for your app, includ
14
14
 
15
15
  ### 1. Enable auth
16
16
 
17
- Add a provider to `void.json`. Email/password is the default, so the simplest config is:
17
+ Add a provider to `void.config.ts`. Email/password is the default, so the simplest config is:
18
18
 
19
19
  ```json
20
20
  {
@@ -91,7 +91,7 @@ Auth turns on automatically when you:
91
91
 
92
92
  - import anything from `void/auth`
93
93
  - import `auth` from `void/client`
94
- - add `auth` to `void.json`
94
+ - add `auth` to `void.config.ts`
95
95
  - add a root-level `auth.ts` file
96
96
 
97
97
  The simplest setup is no config at all. Email/password auth is enabled by default.
@@ -23,7 +23,7 @@ None. D1 is the default dialect, so you can start by defining your schema and qu
23
23
 
24
24
  ## Local Database
25
25
 
26
- `void dev` and local `void db` commands share the same database. If your root `wrangler.jsonc` or `wrangler.json` already declares the D1 binding, Void uses its ID. A `preview_database_id` takes precedence during local development.
26
+ `void dev` and local `void db` commands share the same database. If `cloudflare.d1_databases` in `void.config.ts` declares the D1 binding, Void uses its ID. A `preview_database_id` takes precedence during local development.
27
27
 
28
28
  To store local data outside `.void`, set `voidPlugin({ persistTo: 'local-state' })` in your Vite config. Start `void dev` once to record that directory before running database commands. After changing the Vite config, start `void dev` again to refresh it. Frameworks that manage their own Cloudflare runtime use `.wrangler/state`.
29
29
 
@@ -8,7 +8,7 @@ Void supports MySQL through [Cloudflare Hyperdrive](https://developers.cloudflar
8
8
 
9
9
  ## Configure
10
10
 
11
- Set the dialect in `void.json`:
11
+ Set the dialect in `void.config.ts`:
12
12
 
13
13
  ```json
14
14
  {
@@ -16,7 +16,7 @@ Void can provision the Hyperdrive configuration from your connection string. Dir
16
16
 
17
17
  ### 1. Set the database
18
18
 
19
- Add to your `void.json`:
19
+ Add to your `void.config.ts`:
20
20
 
21
21
  ```json
22
22
  {
@@ -43,7 +43,7 @@ Your project uses PostgreSQL. Enter your connection string:
43
43
  > postgresql://user:password@host:5432/mydb?sslmode=require
44
44
  ```
45
45
 
46
- Void provisions Hyperdrive and records its config ID. The connection string isn't written to `wrangler.jsonc` or generated Worker config.
46
+ Void provisions Hyperdrive and records its config ID. The connection string isn't written to `void.config.ts`, `void.lock.json`, or generated Worker config.
47
47
  Both `postgres://` and `postgresql://` URLs are supported, including provider-supplied query strings such as `?sslmode=require`.
48
48
 
49
49
  For a linked Void project, you can also configure the connection with `void db set-url`. For a direct Cloudflare deploy, export the production `DATABASE_URL` in your shell.
@@ -99,7 +99,7 @@ When deploying a PostgreSQL project to a Void platform:
99
99
  When deploying to your own account with `void deploy --platform cloudflare`, export the production
100
100
  connection string as `DATABASE_URL`. Void uses it to provision Hyperdrive and apply the checked-in
101
101
  migrations transactionally before it uploads the Worker. The connection string is not written to
102
- `wrangler.jsonc` or the generated Worker config.
102
+ `void.config.ts`, `void.lock.json`, or the generated Worker config.
103
103
 
104
104
  ## Updating the Connection String
105
105
 
@@ -14,23 +14,23 @@ Direct Cloudflare deployment runs an application in your account. A self-hosted
14
14
  Void platform provides that deployment service to a team using the operator's
15
15
  account. Both use the same application APIs, with the following differences:
16
16
 
17
- | Feature | Direct Cloudflare | Core self-hosted platform |
18
- | ------------------------------------------------ | -------------------------------- | ----------------------------------------- |
19
- | Static sites, SPAs, and native Pages SSR | Supported | Supported |
20
- | Routing rules, WebSockets, queues, cron, and ISR | Supported | Supported |
21
- | D1, KV, R2, and external SQL through Hyperdrive | Supported | Supported |
22
- | Workers AI and provider requests | Your account and gateway | Installation gateway and proxy |
23
- | Runtime logs | Live Cloudflare tail | Retained platform logs |
24
- | Application rollback | Worker versions | Retained platform deployments |
25
- | Typed Durable State | Supported | Unavailable |
26
- | Sandboxes | Requires Workers Paid and Docker | Unavailable in beta |
27
- | Custom application domains | Supported | Unavailable in the core installation |
28
- | Generated GitHub deployment workflow | Supported | Use your CI with a scoped developer token |
29
- | User dashboard and managed GitHub builds | Not required | Not included in a standard installation |
17
+ | Feature | Direct Cloudflare | Core self-hosted platform |
18
+ | ------------------------------------------------ | -------------------------------- | --------------------------------------------- |
19
+ | Static sites, SPAs, and native Pages SSR | Supported | Supported |
20
+ | Routing rules, WebSockets, queues, cron, and ISR | Supported | Supported |
21
+ | D1, KV, R2, and external SQL through Hyperdrive | Supported | Supported |
22
+ | Workers AI and provider requests | Your account and gateway | Installation gateway and proxy |
23
+ | Runtime logs | Live Cloudflare tail | Retained platform logs |
24
+ | Application rollback | Worker versions | Retained platform deployments |
25
+ | Typed Durable State | Supported | Unavailable |
26
+ | Sandboxes | Requires Workers Paid and Docker | Requires Workers Paid on the platform account |
27
+ | Custom application domains | Supported | Unavailable in the core installation |
28
+ | Generated GitHub deployment workflow | Supported | Use your CI with a scoped developer token |
29
+ | User dashboard and managed GitHub builds | Not required | Not included in a standard installation |
30
30
 
31
31
  Ordinary native applications remain compatible with Workers Free within its
32
32
  quotas. Installing a team platform requires Workers for Platforms and the
33
- [documented infrastructure](./self-hosted-platform.md#cloudflare-footprint).
33
+ [documented infrastructure](./platform/installation/domains.md#cloudflare-footprint).
34
34
  Application rollback never reverses database migrations.
35
35
 
36
36
  Routing-rule parity applies to native Void applications and static deployments.
@@ -50,7 +50,7 @@ void deploy # builds and deploys to the saved platform
50
50
 
51
51
  During setup, Void asks where you want to deploy:
52
52
 
53
- - **Cloudflare:** sign in through your browser and choose an account. Void saves the account in `wrangler.jsonc`.
53
+ - **Cloudflare:** sign in through your browser and choose an account. Void saves the account in `void.config.ts` or `void.lock.json`.
54
54
  - **Void:** connect to a platform, sign in, and link or create a project.
55
55
  - **Skip:** set up deployment later with `void connect`.
56
56
 
@@ -247,7 +247,7 @@ See the [Cloudflare guide](../integrations/cloudflare.md#deploy-to-your-own-clou
247
247
 
248
248
  ### Node.js, Bun, and Deno
249
249
 
250
- Set [`target`](../reference/config.md#target) in `void.json` to build a standalone server for Node.js, Bun, or Deno. You can run the result on your own server or in a container.
250
+ Set [`target`](../reference/config.md#target) in `void.config.ts` to build a standalone server for Node.js, Bun, or Deno. You can run the result on your own server or in a container.
251
251
 
252
252
  Deploy `dist/ssr` and `dist/client` together. The server loads the Pages client manifest and assets relative to its emitted module; start it from the app root with `node dist/ssr/index.js`, `bun dist/ssr/index.js`, or `deno run -A dist/ssr/index.js`.
253
253
 
@@ -8,7 +8,7 @@ Use a Durable Object when requests need to share state under one name, such as a
8
8
 
9
9
  Void turns each module in `durable-objects/` into a SQLite-backed Cloudflare Durable Object. The filename determines the binding, Worker class, and initial Cloudflare migration, so no manual Cloudflare configuration is needed.
10
10
 
11
- Void writes the inferred binding and migration entry to `wrangler.jsonc`. Commit that file: Cloudflare Durable Object migrations are append-only, and the persisted order ensures a newly added module is migrated after every class already deployed.
11
+ Void records the inferred binding and migration entry in `void.lock.json`. Commit that file: Cloudflare Durable Object migrations are append-only, and the persisted order ensures a newly added module is migrated after every class already deployed.
12
12
 
13
13
  ## Define state and methods
14
14
 
@@ -129,7 +129,7 @@ export default Counter;
129
129
 
130
130
  These state migrations are separate from Cloudflare's Durable Object class migration. Void generates the latter with `new_sqlite_classes` when it discovers the file.
131
131
 
132
- Do not delete or reorder generated Durable Object migrations in `wrangler.jsonc` after deployment. Native Cloudflare beta deploys can create these classes with the Worker's first deployment, but do not yet apply a later class migration to an existing Worker. Additions, renames, and removals require an explicit supported Cloudflare deployment workflow; after its migration tag is active, `void deploy --platform cloudflare` can resume ordinary version uploads.
132
+ Do not delete or reorder generated Durable Object migrations in `void.lock.json` after deployment. Native Cloudflare beta deploys can create these classes with the Worker's first deployment, but do not yet apply a later class migration to an existing Worker. Additions, renames, and removals require an explicit supported Cloudflare deployment workflow; after its migration tag is active, `void deploy --platform cloudflare` can resume ordinary version uploads.
133
133
 
134
134
  ## Deployment support
135
135
 
@@ -4,7 +4,7 @@ outline: deep
4
4
 
5
5
  # Custom Headers
6
6
 
7
- Define custom response headers in [`void.json`](../../reference/config) using the `routing.headers` field. Keys are URL patterns, values are arrays of `"Name: value"` strings.
7
+ Define custom response headers in [`void.config.ts`](../../reference/config) using the `routing.headers` field. Keys are URL patterns, values are arrays of `"Name: value"` strings.
8
8
 
9
9
  ```json
10
10
  {
@@ -72,14 +72,14 @@ Header rules do not apply to:
72
72
 
73
73
  Meta-frameworks like SvelteKit, Nuxt, and Astro generate a `_headers` file with cache rules for their hashed asset directories. Void automatically parses this file during deploy and merges the rules into the deploy manifest.
74
74
 
75
- - Framework-generated rules are applied **before** `void.json` rules. Since the last match wins, `routing.headers` in `void.json` takes precedence and can override framework defaults.
75
+ - Framework-generated rules are applied **before** `void.config.ts` rules. Since the last match wins, `routing.headers` in `void.config.ts` takes precedence and can override framework defaults.
76
76
  - The `_headers` file is not uploaded as a static asset. Its contents are parsed and included in the manifest only.
77
77
 
78
78
  No configuration is needed. If the framework generates a `_headers` file, it is picked up automatically.
79
79
 
80
80
  ## How headers work
81
81
 
82
- 1. `void deploy` reads header rules from the framework `_headers` file (if present) and `routing.headers` in `void.json`, then includes them in the deploy manifest.
82
+ 1. `void deploy` reads header rules from the framework `_headers` file (if present) and `routing.headers` in `void.config.ts`, then includes them in the deploy manifest.
83
83
  2. The platform stores the rules in the KV routing entry for your project.
84
84
  3. The dispatch Worker adds matching headers before returning a response. Most cached responses include those headers. Hashed assets get header rules on each response, including cache hits, so a rule change takes effect without changing the file.
85
85
 
@@ -61,7 +61,7 @@ export default defineRender(async (c, assetTags) => {
61
61
 
62
62
  ## Relationship to revalidation
63
63
 
64
- Setting `routing.isr: false` in `void.json` disables ISR and this edge-prerendering behavior, including per-page exports. It does not disable build-time HTML generation with `output: "static"`.
64
+ Setting `routing.isr: false` in `void.config.ts` disables ISR and this edge-prerendering behavior, including per-page exports. It does not disable build-time HTML generation with `output: "static"`.
65
65
 
66
66
  Pages with long revalidate TTLs (e.g. 1 year) are effectively static, but the first visitor after a deploy hits a cold cache. This is where prerendering helps - it ensures your users never get slow requests.
67
67
 
@@ -4,7 +4,7 @@ outline: deep
4
4
 
5
5
  # Redirects
6
6
 
7
- Define URL redirects in [`void.json`](../../reference/config) using the `routing.redirects` field. Keys are source URL patterns, values are destination strings or objects with an explicit status.
7
+ Define URL redirects in [`void.config.ts`](../../reference/config) using the `routing.redirects` field. Keys are source URL patterns, values are destination strings or objects with an explicit status.
8
8
 
9
9
  ```json
10
10
  {
@@ -100,16 +100,16 @@ Reads as "when a request hits `old.example.com` on any path, send a 301 to the s
100
100
 
101
101
  Meta-frameworks may generate a `_redirects` file during build. Void parses this file at deploy time and merges the rules into the deploy manifest.
102
102
 
103
- - `void.json` rules are applied **before** framework-generated `_redirects` rules. Since the first match wins, `routing.redirects` in `void.json` takes precedence.
103
+ - `void.config.ts` rules are applied **before** framework-generated `_redirects` rules. Since the first match wins, `routing.redirects` in `void.config.ts` takes precedence.
104
104
  - Both 3xx redirect rules and status `200` [rewrite rules](./rewrites) are supported in `_redirects` files.
105
105
  - The `!` force suffix is only meaningful on `200` entries (see [rewrites — `_redirects` file](./rewrites#redirects-file)). On 3xx entries (`301!`, `302!`, `307!`, `308!`) it's silently stripped — a redirect always "forces" by nature, so the suffix is redundant. `void deploy` prints a single aggregated warning tallying every such entry so you can clean them up.
106
106
  - The `_redirects` file is not uploaded as a static asset. Its contents are parsed and included in the manifest only.
107
107
 
108
- Precedence when the same source appears in both sources follows the same rules as rewrites — config rules are merged before file rules within each phase, and first match wins, so `void.json` overrides `_redirects`. See [Precedence: `_redirects` vs `void.json`](./rewrites#precedence-redirects-vs-void-json) for the full explanation and a worked example.
108
+ Precedence when the same source appears in both sources follows the same rules as rewrites — config rules are merged before file rules within each phase, and first match wins, so `void.config.ts` overrides `_redirects`. See [rewrite precedence](./rewrites.md) for a worked example.
109
109
 
110
110
  ## How redirects work
111
111
 
112
- 1. `void deploy` reads redirect rules from the framework `_redirects` file (if present) and `routing.redirects` in `void.json`, then includes them in the deploy manifest.
112
+ 1. `void deploy` reads redirect rules from the framework `_redirects` file (if present) and `routing.redirects` in `void.config.ts`, then includes them in the deploy manifest.
113
113
  2. The platform stores the rules in the KV routing entry for your project.
114
114
  3. The dispatch worker checks redirect rules before any worker invocation, so matching requests get a redirect response immediately.
115
115
 
@@ -6,13 +6,13 @@ outline: deep
6
6
 
7
7
  Revalidation caches rendered pages and refreshes them in the background. When a cached page becomes stale, visitors can keep reading it while the Worker renders an updated version. This is often called [Incremental Static Regeneration (ISR)](https://vercel.com/docs/incremental-static-regeneration).
8
8
 
9
- This requires [SSR](../ssr.md) or [Pages mode](../pages-routing/overview) to be configured.
9
+ Use revalidation with [Void SSR](../ssr.md), [Pages mode](../pages-routing/overview), or a [supported SSR framework](../../integrations/frameworks/overview.md). For framework apps, Void caches public HTML document responses, not framework data requests.
10
10
 
11
- To disable Void's ISR caching across the app while keeping your per-page settings, set `"routing": { "isr": false }` in `void.json`. This overrides per-page revalidate and prerender policies. Set `isr` back to `true` to enable those policies again. Build-time HTML generation with `output: "static"` is unaffected.
11
+ To disable Void's ISR caching across the app while keeping your per-page settings, set `"routing": { "isr": false }` in `void.config.ts`. This overrides per-page revalidate and prerender policies. Set `isr` back to `true` to enable those policies again. Build-time HTML generation with `output: "static"` is unaffected.
12
12
 
13
13
  ## Enabling revalidation
14
14
 
15
- Add a `routing.revalidate` field to `void.json` with a TTL in seconds:
15
+ Add a `routing.revalidate` field to `void.config.ts` with a TTL in seconds:
16
16
 
17
17
  ```json
18
18
  {
@@ -61,7 +61,7 @@ export const loader = defineHandler(async (c) => {
61
61
  });
62
62
  ```
63
63
 
64
- Per-page values take precedence over `void.json` patterns.
64
+ Per-page values take precedence over `void.config.ts` patterns.
65
65
 
66
66
  ## Precedence
67
67
 
@@ -69,8 +69,8 @@ When multiple sources set a revalidate TTL, the most specific wins:
69
69
 
70
70
  1. `x-revalidate` response header (per-response)
71
71
  2. `.server.ts` export (per-page, Pages mode only)
72
- 3. `void.json` `routing.revalidate` path pattern match
73
- 4. `void.json` `routing.revalidate` global number or `"*"` fallback
72
+ 3. `void.config.ts` `routing.revalidate` path pattern match
73
+ 4. `void.config.ts` `routing.revalidate` global number or `"*"` fallback
74
74
 
75
75
  ## How revalidation works
76
76
 
@@ -6,7 +6,7 @@ outline: deep
6
6
 
7
7
  A rewrite serves one route's content at another URL while keeping the browser's address unchanged. For example, `/docs` can serve the content from `/en/docs`.
8
8
 
9
- Define source patterns and destination paths in `routing.rewrites` in [`void.json`](../../reference/config):
9
+ Define source patterns and destination paths in `routing.rewrites` in [`void.config.ts`](../../reference/config):
10
10
 
11
11
  ```json
12
12
  {
@@ -240,7 +240,7 @@ So a SPA app can carve out specific paths without losing the SPA shell behavior
240
240
 
241
241
  With this config, an asset miss under `/docs/getting-started` resolves to `/docs.html`, while an asset miss under `/app/settings` still resolves to `/index.html` (the SPA default).
242
242
 
243
- You don't need to write `"/*": "/index.html"` yourself — the CLI **appends** a synthetic `{ source: '/*', destination: '/index.html' }` rule to the fallback list when packaging a SPA deploy that has user fallbacks. Because evaluation is first-match-wins, user rules come before the synthetic entry and take precedence; the synthetic rule only fires when no user rule matched. This is why the shipped manifest may contain more fallback rules than you wrote in `void.json`. If you do write `"/*": "/index.html"` yourself, the CLI emits a warning on `void deploy` noting that the rule duplicates the default and can be omitted.
243
+ You don't need to write `"/*": "/index.html"` yourself — the CLI **appends** a synthetic `{ source: '/*', destination: '/index.html' }` rule to the fallback list when packaging a SPA deploy that has user fallbacks. Because evaluation is first-match-wins, user rules come before the synthetic entry and take precedence; the synthetic rule only fires when no user rule matched. This is why the shipped manifest may contain more fallback rules than you wrote in `void.config.ts`. If you do write `"/*": "/index.html"` yourself, the CLI emits a warning on `void deploy` noting that the rule duplicates the default and can be omitted.
244
244
 
245
245
  ## `_redirects` file
246
246
 
@@ -254,25 +254,25 @@ Rewrites can also be defined in a `_redirects` file placed in Vite's `publicDir`
254
254
  /docs/* /en/docs/:splat 200!
255
255
  ```
256
256
 
257
- | File-based form | `void.json` equivalent | Behavior |
258
- | --------------- | ---------------------- | ------------------------------------------------------------------------ |
259
- | `... 200` | `routing.fallbacks` | Fires only when no static asset and no route matched (would have 404'd). |
260
- | `... 200!` | `routing.rewrites` | Always fires, overriding any static asset that would have served. |
257
+ | File-based form | `void.config.ts` equivalent | Behavior |
258
+ | --------------- | --------------------------- | ------------------------------------------------------------------------ |
259
+ | `... 200` | `routing.fallbacks` | Fires only when no static asset and no route matched (would have 404'd). |
260
+ | `... 200!` | `routing.rewrites` | Always fires, overriding any static asset that would have served. |
261
261
 
262
- - `void.json` rules are applied **before** file-based rules. Since the first match wins, `routing.rewrites` / `routing.fallbacks` in `void.json` take precedence.
262
+ - `void.config.ts` rules are applied **before** file-based rules. Since the first match wins, `routing.rewrites` / `routing.fallbacks` in `void.config.ts` take precedence.
263
263
  - The `_redirects` file can mix 3xx redirects, `200` fallbacks, and `200!` force rewrites. Ordering is preserved within each bucket.
264
264
  - The `!` force suffix is only meaningful on `200`. On a 3xx entry like `301!`, the `!` is silently stripped — 3xx redirects always "force" by their nature (they change the URL), so the suffix is meaningless. `void deploy` prints a single aggregated warning tallying all `301!` / `302!` / `307!` / `308!` entries so you can clean them up.
265
265
 
266
- ## Precedence: `_redirects` vs `void.json`
266
+ ## Precedence: `_redirects` vs `void.config.ts`
267
267
 
268
- When the same source pattern appears in both a `_redirects` file and `void.json` (`routing.redirects` / `routing.rewrites` / `routing.fallbacks`), the rules don't replace each other — they **merge into a single ordered list per phase**, and the first match wins.
268
+ When the same source pattern appears in both a `_redirects` file and `void.config.ts` (`routing.redirects` / `routing.rewrites` / `routing.fallbacks`), the rules don't replace each other — they **merge into a single ordered list per phase**, and the first match wins.
269
269
 
270
270
  Rules are bucketed by phase before merging:
271
271
 
272
272
  - **Pre-asset phase** (always fires, runs before static asset lookup): `routing.redirects` + `routing.rewrites` + `_redirects` 3xx entries + `_redirects` `200!` entries.
273
273
  - **Post-asset phase** (only fires on an asset miss): `routing.fallbacks` + `_redirects` plain `200` entries. For SPA app types, the synthetic `/* → /index.html` rule is **appended last** in this phase, so user fallbacks evaluated earlier take precedence under first-match-wins.
274
274
 
275
- Within each phase, `void.json` rules run first, followed by `_redirects` rules. The first matching rule wins, so a `void.json` rule takes precedence over the same source pattern in `_redirects`.
275
+ Within each phase, `void.config.ts` rules run first, followed by `_redirects` rules. The first matching rule wins, so a `void.config.ts` rule takes precedence over the same source pattern in `_redirects`.
276
276
 
277
277
  ### Concrete example
278
278
 
@@ -281,26 +281,27 @@ Within each phase, `void.json` rules run first, followed by `_redirects` rules.
281
281
  /docs/* /en/docs/:splat 200!
282
282
  ```
283
283
 
284
- ```json
285
- // void.json
286
- {
287
- "routing": {
288
- "rewrites": {
289
- "/docs/*": "/handbook/:splat"
290
- }
291
- }
292
- }
284
+ ```ts
285
+ import { defineConfig } from 'void/config';
286
+
287
+ export default defineConfig({
288
+ routing: {
289
+ rewrites: {
290
+ '/docs/*': '/handbook/:splat',
291
+ },
292
+ },
293
+ });
293
294
  ```
294
295
 
295
- A request to `/docs/intro` matches both rules. Merged order is `[void.json: /docs/* → /handbook/:splat, _redirects: /docs/* → /en/docs/:splat]`, so `void.json` wins and the request resolves to `/handbook/intro`.
296
+ A request to `/docs/intro` matches both rules. Merged order is `[void.config.ts: /docs/* → /handbook/:splat, _redirects: /docs/* → /en/docs/:splat]`, so `void.config.ts` wins and the request resolves to `/handbook/intro`.
296
297
 
297
- To confirm precedence in practice, check the [`X-Void-Routing` dev header](#debugging-with-x-void-routing) on any response during `vite dev` — it names the winning rule and its origin (`_redirects:<line>` vs `void.json#routing.rewrites`).
298
+ To confirm precedence in practice, check the [`X-Void-Routing` dev header](#debugging-with-x-void-routing) on any response during `vite dev` — it names the winning rule and its origin (`_redirects:<line>` vs `void.config.ts#routing.rewrites`).
298
299
 
299
300
  ## How rewrites work
300
301
 
301
- **Static rewrites** (`void.json` and `_redirects` file) on managed Void deployments:
302
+ **Static rewrites** (`void.config.ts` and `_redirects` file) on managed Void deployments:
302
303
 
303
- 1. `void deploy` reads rewrite rules from the `_redirects` file (status `200` entries) and `routing.rewrites` in `void.json`, then includes them in the deploy manifest alongside redirect rules.
304
+ 1. `void deploy` reads rewrite rules from the `_redirects` file (status `200` entries) and `routing.rewrites` in `void.config.ts`, then includes them in the deploy manifest alongside redirect rules.
304
305
  2. The platform stores the rules in the KV routing entry for your project.
305
306
  3. The dispatch worker evaluates all routing rules (redirects and rewrites) before any worker invocation. If a rewrite matches, the request pathname is updated internally and the request continues through the normal pipeline (static assets, ISR, worker). The original URL is passed as `X-Void-Original-URL`.
306
307
 
@@ -337,16 +338,16 @@ During `vite dev`, every response carries an `X-Void-Routing` header that traces
337
338
 
338
339
  ```
339
340
  X-Void-Routing: redirect[/old] -> /new 301 (_redirects:12)
340
- X-Void-Routing: rewrite[/api/*] -> /backend/:splat (void.json#routing.rewrites)
341
- X-Void-Routing: fallback[/docs/*] -> /docs.html (void.json#routing.fallbacks)
341
+ X-Void-Routing: rewrite[/api/*] -> /backend/:splat (void.config.ts#routing.rewrites)
342
+ X-Void-Routing: fallback[/docs/*] -> /docs.html (void.config.ts#routing.fallbacks)
342
343
  X-Void-Routing: c.rewrite -> /new-path (middleware)
343
344
  X-Void-Routing: pass-through
344
345
  ```
345
346
 
346
- Phases are separated by `->` so the diagnostic value stays valid as an HTTP header. The parenthesised source hint points at the exact declaration — a line number for `_redirects`, a config path for `void.json`, or `spa-default` for the synthetic SPA catch-all. The header is **only emitted in dev** — production builds strip both the trace code and the per-rule `origin` metadata from the bundle and manifest.
347
+ Phases are separated by `->` so the diagnostic value stays valid as an HTTP header. The parenthesised source hint points at the exact declaration — a line number for `_redirects`, a config path for `void.config.ts`, or `spa-default` for the synthetic SPA catch-all. The header is **only emitted in dev** — production builds strip both the trace code and the per-rule `origin` metadata from the bundle and manifest.
347
348
 
348
349
  ::: info What fires in `vite dev`
349
- `vite dev` applies the full static routing pipeline on every target — `node`, `bun`, `deno`, and the default target alike. `void.json` rules (`routing.redirects` / `routing.rewrites` / `routing.fallbacks` / `routing.headers`) and file-based rules (`public/_redirects`, `public/_headers`) are merged at plugin load and compiled into the Hono middleware your worker runs behind. Editing `_redirects` or `_headers` during a dev session re-runs the merge and reloads the page — no restart needed. `c.rewrite()` calls in middleware work everywhere because they live inside the worker itself, and the `X-Void-Routing` dev header reports every decision on every target.
350
+ `vite dev` applies the full static routing pipeline on every target — `node`, `bun`, `deno`, and the default target alike. `void.config.ts` rules (`routing.redirects` / `routing.rewrites` / `routing.fallbacks` / `routing.headers`) and file-based rules (`public/_redirects`, `public/_headers`) are merged at plugin load and compiled into the Hono middleware your worker runs behind. Editing `_redirects` or `_headers` during a dev session re-runs the merge and reloads the page — no restart needed. `c.rewrite()` calls in middleware work everywhere because they live inside the worker itself, and the `X-Void-Routing` dev header reports every decision on every target.
350
351
 
351
352
  A few things still only run in the deployed runtime, not `vite dev`:
352
353
 
@@ -135,7 +135,7 @@ For direct Cloudflare deployment, these frameworks need a complete `assets` poli
135
135
 
136
136
  ### Generated config
137
137
 
138
- Void owns the generated asset routing policy during dev and build for Void apps. If a root `wrangler.jsonc` contains stale `not_found_handling` or `run_worker_first` values, Void replaces those fields so generated config cannot accidentally change which layer sees a request first.
138
+ Void owns the generated asset routing policy during dev and build for Void apps. If `cloudflare.assets` in `void.config.ts` contains stale `not_found_handling` or `run_worker_first` values, Void replaces those fields so generated config cannot accidentally change which layer sees a request first.
139
139
 
140
140
  TanStack Start and React Router are the exception: Void generates no asset policy for them and leaves both fields to your own Cloudflare config. Writing `not_found_handling` alone would make the asset layer answer unmatched requests and the framework Worker would never run, and completing the policy needs `assets.binding` and `assets.directory` that the framework owns, not Void.
141
141