void 0.7.12 → 0.8.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 (142) hide show
  1. package/AGENT_PROMPT.md +1 -1
  2. package/README.md +2 -2
  3. package/dist/{agents-DqkFfc2c.mjs → agents-Dkgafwfr.mjs} +1 -1
  4. package/dist/{auth-cmd-bS88H4Lb.mjs → auth-cmd-B1-7r6ng.mjs} +3 -3
  5. package/dist/{better-auth-shared-D2JaoCs4.mjs → better-auth-shared-CbAF6sOM.mjs} +1 -1
  6. package/dist/{better-auth-shared-HXlHRw02.d.mts → better-auth-shared-Fzyk5yS1.d.mts} +2 -7
  7. package/dist/{cache-DUDCNty6.mjs → cache-CGYC-2LW.mjs} +5 -5
  8. package/dist/{cancel-deploy-DOuSbPwX.mjs → cancel-deploy-B4j31z7d.mjs} +4 -4
  9. package/dist/canonical-json-CEyQaVDa.mjs +13 -0
  10. package/dist/cli/cli.mjs +44 -31
  11. package/dist/{client-C_DYiXeu.mjs → client-C-nH6yz3.mjs} +5 -5
  12. package/dist/{collect-HqAuilH6.mjs → collect-9rO3JFNM.mjs} +1 -1
  13. package/dist/{config-DyUSwbeX.mjs → config--wXmVOoe.mjs} +10 -8
  14. package/dist/{config-CeRQg3Lz.mjs → config-BVEC0lti.mjs} +11 -2
  15. package/dist/{config-CvHtTM0q.mjs → config-hhMYPVRT.mjs} +3 -12
  16. package/dist/{create-project-hvFe6rbI.mjs → create-project-BGnQMy5N.mjs} +44 -18
  17. package/dist/{db-YEYSTfGw.mjs → db-CT5Xg6ds.mjs} +42 -37
  18. package/dist/{delete-XyM_VD9o.mjs → delete-eMGTHHB9.mjs} +5 -5
  19. package/dist/{deploy-CPAEgVQm.mjs → deploy-7EA_lKq9.mjs} +169 -99
  20. package/dist/{discover-CKGQpis8.mjs → discover-C8N1I4tK.mjs} +9 -6
  21. package/dist/{domain-Dvj7u8tr.mjs → domain-UfLrp2vc.mjs} +64 -22
  22. package/dist/{drizzle-Cx7cVwrE.mjs → drizzle-DmaANP4-.mjs} +1 -1
  23. package/dist/{env-Bjl0rzuf.mjs → env-Cvdbbm_N.mjs} +7 -7
  24. package/dist/{env-helpers-Dw95CU8e.d.mts → env-helpers-Bt9yYg5I.d.mts} +1 -1
  25. package/dist/{env-types-BSQghXbx.mjs → env-types-D6qI1ThV.mjs} +8 -19
  26. package/dist/{env-validation-Buy5pe3u.mjs → env-validation-DBJsxZLz.mjs} +4 -4
  27. package/dist/{gen-DU8NIdrH.mjs → gen-Cn2hZ8RR.mjs} +37 -31
  28. package/dist/{handler-DJTuxB10.d.mts → handler-BPhL8AmU.d.mts} +3 -3
  29. package/dist/{headers-CuVHn6Kl.mjs → headers-wAPJigtE.mjs} +3 -3
  30. package/dist/index.d.mts +3 -3
  31. package/dist/index.mjs +273 -104
  32. package/dist/{init-iIiQWzyB.mjs → init-DL6syXuF.mjs} +124 -38
  33. package/dist/{link-DdXqlUiJ.mjs → link-C5x1E-XZ.mjs} +5 -5
  34. package/dist/{list-9Bxa5Odn.mjs → list-ezL7hqDV.mjs} +5 -5
  35. package/dist/{login-C_MfDjhu.mjs → login-CkLr-AaI.mjs} +3 -3
  36. package/dist/{logs-DjqCpEER.mjs → logs-MnGILmLz.mjs} +4 -4
  37. package/dist/{mcp-vA0880_K.mjs → mcp-B84MmVAW.mjs} +3 -3
  38. package/dist/{node-gxRQXIRT.mjs → node-fpywdcbN.mjs} +6 -6
  39. package/dist/{output-D3g5otMC.mjs → output-DeiS4oEX.mjs} +1 -1
  40. package/dist/pages/client.d.mts +1 -1
  41. package/dist/pages/head-client.d.mts +1 -1
  42. package/dist/pages/head.d.mts +1 -1
  43. package/dist/pages/index.d.mts +28 -3
  44. package/dist/pages/index.mjs +6 -5
  45. package/dist/pages/islands-plugin.d.mts +1 -1
  46. package/dist/pages/islands-plugin.mjs +15 -14
  47. package/dist/pages/protocol.d.mts +2 -2
  48. package/dist/pages/protocol.mjs +1 -1
  49. package/dist/{pathe.M-eThtNZ-D-kmWkCS.mjs → pathe.M-eThtNZ-BrPhGF_K.mjs} +1 -1
  50. package/dist/plan-aD3wRDqF.mjs +271 -0
  51. package/dist/{plugin-inference-BexV6LL3.mjs → plugin-inference-Ba1uGdIy.mjs} +26 -20
  52. package/dist/{prepare-BEkH89oX.mjs → prepare-BrAISonG.mjs} +29 -19
  53. package/dist/{preset-CYQh93UF.mjs → preset-BRsCi8ZB.mjs} +10 -8
  54. package/dist/{project-DhB4A8_g.mjs → project-CH9pdo16.mjs} +1 -1
  55. package/dist/{project-cmd-CeXO06hG.mjs → project-cmd-JQUzv3qF.mjs} +10 -10
  56. package/dist/project-paths-CCMrHYQm.mjs +100 -0
  57. package/dist/{project-slug-KRvHQEQI.mjs → project-slug-De4UjtD9.mjs} +0 -1
  58. package/dist/{project-tsconfig-Bfy55qvs.mjs → project-tsconfig-HAGjfY6w.mjs} +10 -5
  59. package/dist/{protocol-D7r_deVZ.d.mts → protocol-mcSsdMij.d.mts} +3 -3
  60. package/dist/providers--_pvxpNN.d.mts +7 -0
  61. package/dist/{resolve-project-DdjLQ2tB.mjs → resolve-project-CNpUbUHd.mjs} +1 -1
  62. package/dist/{rollback-C8OSMxmq.mjs → rollback-CoAAvC18.mjs} +4 -4
  63. package/dist/{route-types-qVL-v-CB.mjs → route-types-jxRfWuCb.mjs} +1 -1
  64. package/dist/{runner-C0d3lJo1.mjs → runner-BkGBfr4e.mjs} +4 -2
  65. package/dist/{runner-pg-Bd_172vF.mjs → runner-pg-BXP0JpHW.mjs} +1 -1
  66. package/dist/runtime/ai.mjs +2 -2
  67. package/dist/runtime/auth.d.mts +1 -1
  68. package/dist/runtime/better-auth-pg.d.mts +1 -1
  69. package/dist/runtime/better-auth-pg.mjs +2 -2
  70. package/dist/runtime/better-auth.d.mts +1 -1
  71. package/dist/runtime/better-auth.mjs +2 -2
  72. package/dist/runtime/client.d.mts +2 -2
  73. package/dist/runtime/client.mjs +1 -1
  74. package/dist/runtime/env-helpers.d.mts +1 -1
  75. package/dist/runtime/env-public-client.d.mts +1 -1
  76. package/dist/runtime/env-public.d.mts +2 -2
  77. package/dist/runtime/env-public.mjs +1 -1
  78. package/dist/runtime/env.mjs +1 -1
  79. package/dist/runtime/fetch-stream.d.mts +1 -1
  80. package/dist/runtime/fetch-stream.mjs +1 -1
  81. package/dist/runtime/fetch.d.mts +1 -1
  82. package/dist/runtime/fetch.mjs +1 -1
  83. package/dist/runtime/handler.d.mts +1 -1
  84. package/dist/runtime/handler.mjs +1 -1
  85. package/dist/runtime/isr.mjs +1 -1
  86. package/dist/runtime/live.d.mts +2 -2
  87. package/dist/runtime/live.mjs +1 -1
  88. package/dist/runtime/migration-handler.d.mts +33 -1
  89. package/dist/runtime/migration-handler.mjs +398 -23
  90. package/dist/runtime/remote/index.mjs +1 -1
  91. package/dist/runtime/sandbox.d.mts +73 -3
  92. package/dist/runtime/sandbox.mjs +239 -3
  93. package/dist/runtime/validator.d.mts +1 -1
  94. package/dist/runtime/ws-server.d.mts +2 -2
  95. package/dist/runtime/ws.d.mts +3 -3
  96. package/dist/{scan-CKpylFj9.mjs → scan-2YmJkYAf.mjs} +4 -3
  97. package/dist/{scan-CkK1Hzpa.mjs → scan-DzzHqtiT.mjs} +82 -43
  98. package/dist/{secret-NDvlqAN2.mjs → secret-mz8t_CML.mjs} +5 -5
  99. package/dist/{skills-SAG0WyVn.mjs → skills-B_ynF4lA.mjs} +3 -3
  100. package/dist/{subcommand-prompt-q9T06dpg.mjs → subcommand-prompt-CPuV7tPW.mjs} +2 -2
  101. package/dist/sveltekit.mjs +1 -1
  102. package/dist/{validate-DW3ViKTA.mjs → validate-CNWm-PsL.mjs} +49 -9
  103. package/dist/{yarn-pnp-6LD6_3Ej.mjs → yarn-pnp-QgEYVC3V.mjs} +1 -1
  104. package/getting-started-prompt.txt +2 -2
  105. package/package.json +3 -2
  106. package/schema.json +5 -0
  107. package/skills/void/SKILL.md +1 -1
  108. package/skills/void/docs/guide/ai.md +1 -1
  109. package/skills/void/docs/guide/app-types.md +1 -1
  110. package/skills/void/docs/guide/database/postgresql.md +1 -1
  111. package/skills/void/docs/guide/edge/headers.md +1 -1
  112. package/skills/void/docs/guide/edge/static-assets.md +34 -0
  113. package/skills/void/docs/guide/pages-routing/overview.md +1 -1
  114. package/skills/void/docs/guide/quickstart.md +2 -2
  115. package/skills/void/docs/guide/sandboxes.md +3 -2
  116. package/skills/void/docs/guide/ssr.md +25 -2
  117. package/skills/void/docs/integrations/cloudflare.md +5 -3
  118. package/skills/void/docs/integrations/frameworks/overview.md +1 -1
  119. package/skills/void/docs/integrations/nodejs-bun-deno.md +10 -9
  120. package/skills/void/docs/node_modules/void/AGENT_PROMPT.md +1 -1
  121. package/skills/void/docs/node_modules/void/README.md +2 -2
  122. package/skills/void/docs/node_modules/void/skills/void/SKILL.md +1 -1
  123. package/skills/void/docs/reference/api.md +204 -13
  124. package/skills/void/docs/reference/cli.md +55 -7
  125. package/skills/void/docs/reference/config.md +27 -4
  126. package/skills/void/docs/reference/resource-inference.md +1 -1
  127. /package/dist/{auth-DmuALf16.d.mts → auth-SfRBhXan.d.mts} +0 -0
  128. /package/dist/{auth-migrations-BwLPwRgH.mjs → auth-migrations-BqJoGqGQ.mjs} +0 -0
  129. /package/dist/{cf-access-BW8K93Fm.mjs → cf-access-DKDsgwOU.mjs} +0 -0
  130. /package/dist/{defer-2ARBu8Et.mjs → defer-DkoEwda-.mjs} +0 -0
  131. /package/dist/{dist-q8b2Mjgb.mjs → dist-DR9sIMbM.mjs} +0 -0
  132. /package/dist/{dist-D2L3_KTK.mjs → dist-abzUneor.mjs} +0 -0
  133. /package/dist/{dotenv-HQNhRalS.mjs → dotenv-Bkoqyq9r.mjs} +0 -0
  134. /package/dist/{env-raw-DtfQ9E31.mjs → env-raw-zk5JQKZe.mjs} +0 -0
  135. /package/dist/{fetch-error-DZ868Xq4.d.mts → fetch-error-BbixZ9vW.d.mts} +0 -0
  136. /package/dist/{fetch-error-CEr0ACTl.mjs → fetch-error-rXermVU3.mjs} +0 -0
  137. /package/dist/{head-C7QW7UY1.d.mts → head-CZs8dMxG.d.mts} +0 -0
  138. /package/dist/{log-7ChR5Fbc.mjs → log-CWWZV4V1.mjs} +0 -0
  139. /package/dist/{magic-string.es-DS_lmuBe.mjs → magic-string.es-C1Fb0uxq.mjs} +0 -0
  140. /package/dist/{providers-BlFNPYen.mjs → providers-uC0PJg1c.mjs} +0 -0
  141. /package/dist/{standard-schema-D2qvCEYV.d.mts → standard-schema-WhHcCaqJ.d.mts} +0 -0
  142. /package/dist/{types-DG_Ynnyd.d.mts → types-C8wsi1hv.d.mts} +0 -0
@@ -1,4 +1,4 @@
1
- import { a as join, n as dirname } from "./pathe.M-eThtNZ-D-kmWkCS.mjs";
1
+ import { a as join, n as dirname } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
2
2
  import { existsSync, readdirSync } from "node:fs";
3
3
  import { pathToFileURL } from "node:url";
4
4
  //#region src/cli/yarn-pnp.ts
@@ -7,9 +7,9 @@ Then run:
7
7
 
8
8
  npx void init
9
9
 
10
- In an empty directory, `void init` will add the matching Pages adapter and starter dependencies after you choose a framework. In an existing app, it configures Void in place by adding missing Vite scripts and creating or patching `vite.config.*` with `voidPlugin()`.
10
+ In an empty directory, `void init` will add the matching Pages adapter and starter dependencies after you choose a scaffold toolchain and framework. Vite+ is the default toolchain. In an existing app, it configures Void in place by adding missing Vite scripts and creating or patching `vite.config.*` with `voidPlugin()`.
11
11
 
12
- During `void init`, first choose a Pages framework (React, Vue, Svelte, or Solid), then choose D1 for a zero-config, fully managed default or PostgreSQL if you already have Postgres infrastructure or expect heavier writes and more complex queries.
12
+ During `void init`, choose Vite+ unless you specifically want plain Vite scripts, then choose a Pages framework (React, Vue, Svelte, or Solid). Choose D1 for a zero-config, fully managed default or PostgreSQL if you already have Postgres infrastructure or expect heavier writes and more complex queries.
13
13
 
14
14
  At the end of the interactive flow, `void init` can also log you in and link or create your Void project so your first deploy is just:
15
15
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "void",
3
- "version": "0.7.12",
3
+ "version": "0.8.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/voidzero-dev/void.git",
@@ -48,6 +48,7 @@
48
48
  "import": "./dist/index.mjs",
49
49
  "require": "./dist/index.mjs"
50
50
  },
51
+ "./schema.json": "./schema.json",
51
52
  "./handler": {
52
53
  "types": "./dist/runtime/handler.d.mts",
53
54
  "import": "./dist/runtime/handler.mjs",
@@ -332,7 +333,7 @@
332
333
  "valibot": ">=1.0.0-beta.7",
333
334
  "vite": "^8.0.0",
334
335
  "zod": "^3.25.0 || ^4.0.0",
335
- "@void/md": "0.7.12"
336
+ "@void/md": "0.8.0"
336
337
  },
337
338
  "peerDependenciesMeta": {
338
339
  "@void/md": {
package/schema.json CHANGED
@@ -8,6 +8,11 @@
8
8
  "type": "string",
9
9
  "description": "JSON Schema URL for IDE support"
10
10
  },
11
+ "sourceDir": {
12
+ "type": "string",
13
+ "pattern": "^(?!/)(?!\\.\\.?$)(?!\\./$)(?!\\.\\./)(?!.*(?:^|/)\\.\\.(?:/|$))(?!.*\\s$)(?!\\s).+$",
14
+ "description": "Directory containing Void source conventions such as pages, routes, middleware, crons, queues, db, auth.ts, and env.ts. Omit to use the project root."
15
+ },
11
16
  "target": {
12
17
  "type": "string",
13
18
  "enum": ["cloudflare", "node", "bun", "deno"],
@@ -13,7 +13,7 @@ Docs in this skill are bundled from `docs/` during `void` package build and live
13
13
 
14
14
  ## Command Naming
15
15
 
16
- Use `void` in examples and commands in this skill. For first-time setup, prefer `void init` followed by `void deploy`; in an empty directory, install `void` first and let `void init` add the matching Pages adapter and starter dependencies. In an existing app, `void init` configures Void in place by adding missing Vite scripts and creating or patching `vite.config.*` with `voidPlugin()`. `void init` can also handle auth and project linking interactively.
16
+ Use `void` in examples and commands in this skill. For first-time setup, prefer `void init` followed by `void deploy`; in an empty directory, install `void` first and let `void init` add the matching Pages adapter and starter dependencies with Vite+ as the default scaffold toolchain. In an existing app, `void init` configures Void in place by adding missing Vite scripts and creating or patching `vite.config.*` with `voidPlugin()`. `void init` can also handle auth and project linking interactively.
17
17
 
18
18
  Use `void` and `@void/*` in code examples and package manifests.
19
19
 
@@ -208,7 +208,7 @@ All [AI Gateway providers](https://developers.cloudflare.com/ai-gateway/usage/pr
208
208
  For production, add your API key as a project secret:
209
209
 
210
210
  ```bash
211
- void secrets set OPENAI_API_KEY sk-...
211
+ void secret put OPENAI_API_KEY=sk-...
212
212
  ```
213
213
 
214
214
  For local development, add it to `.env.local` in your project root:
@@ -50,7 +50,7 @@ Void supports deploying Vite-based meta-framework apps with `void deploy`. The f
50
50
  | [Analog](https://analogjs.org/) | `@analogjs/platform` | [Guide](../integrations/frameworks/analog.md) |
51
51
  | [Astro](https://astro.build/) | `astro` | [Guide](../integrations/frameworks/astro.md) |
52
52
 
53
- Add `voidPlugin()` to the framework's Vite config to get binding inference, typed DB generation, migration management, auth, cron jobs, queues, and caching. See the [Meta Frameworks Integration](../integrations/frameworks/overview.md) for the full feature matrix, deploy pipeline, and per-framework setup guides.
53
+ Add `voidPlugin()` to the framework's Vite config to get binding inference, typed DB generation, migration management, cron jobs, queues, and caching. Void-managed auth is not supported in framework mode; use Better Auth's official integration for your framework. See the [Meta Frameworks Integration](../integrations/frameworks/overview.md) for the full feature matrix, deploy pipeline, and per-framework setup guides.
54
54
 
55
55
  **Deploy:** `void deploy` runs the framework build, packages the output, and deploys to Void. The framework still owns routing and SSR, while Void handles resource provisioning, migrations, and edge hosting.
56
56
 
@@ -32,7 +32,7 @@ For local development, add `DATABASE_URL` to `.env.local`:
32
32
  DATABASE_URL=postgres://user:password@host:5432/mydb
33
33
  ```
34
34
 
35
- This connects directly to your Postgres database during `void dev`.
35
+ This connects directly to your Postgres database during local Vite development.
36
36
 
37
37
  ### 3. Deploy
38
38
 
@@ -74,6 +74,6 @@ No configuration is needed. If the framework generates a `_headers` file, it is
74
74
 
75
75
  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.
76
76
  2. The platform stores the rules in the KV routing entry for your project.
77
- 3. The dispatch worker applies matching rules to static responses before edge caching.
77
+ 3. The dispatch worker applies matching rules to matching responses before returning them. Cacheable responses are cached with the final headers.
78
78
 
79
79
  Because rules are evaluated at the edge, there is no extra latency cost. Headers are applied inline before the response is returned and cached.
@@ -67,6 +67,40 @@ This happens automatically for all static assets. No configuration is needed.
67
67
 
68
68
  You can override caching headers or add your own for any static asset path using [Custom Headers](./headers).
69
69
 
70
+ ## Request pipeline
71
+
72
+ Static assets can run in front of the worker, behind the worker, or without any worker at all. Void chooses the pipeline from the app shape so static pages stay static unless application code must inspect document navigations.
73
+
74
+ ### Deploy shapes
75
+
76
+ | Shape | Worker deployed | First handler for assets | First handler for document navigations | Miss behavior |
77
+ | --------------------------------------------------------------------------------------- | --------------- | ------------------------ | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
78
+ | `inference.appType: "static"` | No | Asset platform | Asset platform | Platform 404 page. |
79
+ | Static SPA deploy | No | Asset platform | Asset platform | Platform serves `/index.html` for unmatched navigations. If user `routing.fallbacks` exist, Void ships fallback rules. |
80
+ | Void app with only `/api` routes | Yes | Asset platform | Asset platform | Static navigations keep the platform SPA fallback; API asset misses fall through to the worker route table. |
81
+ | Void app with `middleware/`, managed auth, non-`/api` routes, WebSockets, live bindings | Yes | Worker first | Worker first | Asset misses stay 404, then the worker serves `/index.html` for HTML requests after routes and middleware run. |
82
+ | Pages, SSR, and framework apps | Yes | Worker first | Worker first | Asset misses stay 404. Pages, SSR, or framework rendering owns HTML responses, including intentional HTML 404s. |
83
+
84
+ ### Worker-first Void apps
85
+
86
+ For worker-owned HTML, Void sets Cloudflare assets to `not_found_handling: "none"` and configures `run_worker_first`. The request order is:
87
+
88
+ 1. Platform routing rules that always run before assets, such as redirects and forced rewrites.
89
+ 2. Worker route table, middleware, auth, WebSocket upgrades, Pages, or SSR.
90
+ 3. `env.ASSETS.fetch()` from inside the worker for static files.
91
+ 4. For non-Pages, non-SSR Void apps only, a worker-side SPA fallback to `/index.html` when the original request accepts HTML.
92
+ 5. The worker's original 404.
93
+
94
+ This is the path needed for preview auth and other middleware. Cloudflare's platform SPA fallback can serve `index.html` directly for browser navigations; when that happens, middleware never sees the request. Worker-owned HTML avoids that by moving fallback HTML behind middleware.
95
+
96
+ ### Asset-first Void apps
97
+
98
+ For Void apps with only `/api` routes, Void does not enable `run_worker_first`. Static assets and SPA navigations stay on the asset platform. Requests that do not resolve to an asset and are not handled by the platform SPA fallback, such as `/api/hello`, fall through to the worker.
99
+
100
+ ### Generated config
101
+
102
+ Void owns the generated asset routing policy during dev and build. 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.
103
+
70
104
  ## API routes and SSR pages
71
105
 
72
106
  API responses (`/api/*`) and SSR-rendered pages without file extensions always hit the worker. They are **not** edge-cached by the dispatch layer.
@@ -12,7 +12,7 @@ Pages mode is also entirely optional - you can use any client-side router to bui
12
12
 
13
13
  ## Setup
14
14
 
15
- If you start in a scaffoldable empty directory, `void init` can generate this setup for you: it asks whether you want React, Vue, Svelte, or Solid Pages mode, then lets you pick a D1 starter, a PostgreSQL starter, or Static Pages. The database-backed starters write the adapter-aware `vite.config.ts`, `pages/`, and `db/` starter files; Static Pages writes just the basic `pages/` setup so you can grow into server features later.
15
+ If you start in a scaffoldable empty directory, `void init` can generate this setup for you: it asks whether to scaffold with Vite+ (the default) or plain Vite, asks whether you want React, Vue, Svelte, or Solid Pages mode, then lets you pick a D1 starter, a PostgreSQL starter, or Static Pages. The database-backed starters write the adapter-aware `vite.config.ts`, `pages/`, and `db/` starter files; Static Pages writes just the basic `pages/` setup so you can grow into server features later.
16
16
 
17
17
  If you're adding Pages mode manually, install a framework adapter alongside `void`:
18
18
 
@@ -32,9 +32,9 @@ yarn add -D void
32
32
  bun add -D void
33
33
  ```
34
34
 
35
- In an empty directory, `void init` adds the matching Pages adapter and starter dependencies after you choose a framework.
35
+ In an empty directory, `void init` adds the matching Pages adapter and starter dependencies after you choose a scaffold toolchain and framework. Vite+ is the default toolchain and uses `vp` scripts.
36
36
 
37
- As part of `void init`, you'll choose a Pages framework (React, Vue, Svelte, or Solid) and a starter type. D1 is the default top option and scaffolds a DB-backed page loader, schema, generated migration, `db/seed.ts`, and API route. PostgreSQL scaffolds the same starter and writes `"database": "pg"` to `void.json`. Static Pages skips the database and server starter files so you can start with static content and add Void features later.
37
+ As part of `void init`, you'll choose Vite+ or plain Vite, then a Pages framework (React, Vue, Svelte, or Solid) and a starter type. D1 is the default top option and scaffolds a DB-backed page loader, schema, generated migration, `db/seed.ts`, and API route. PostgreSQL scaffolds the same starter and writes `"database": "pg"` to `void.json`. Static Pages skips the database and server starter files so you can start with static content and add Void features later.
38
38
 
39
39
  After installation, run the setup flow:
40
40
 
@@ -12,7 +12,7 @@ import { getSandbox } from 'void/sandbox';
12
12
 
13
13
  export const POST = defineHandler(async (c) => {
14
14
  const { command } = await c.req.json<{ command: string }>();
15
- const sandbox = getSandbox('default');
15
+ const sandbox = await getSandbox('default');
16
16
  const result = await sandbox.exec(command);
17
17
 
18
18
  return c.json(result);
@@ -58,7 +58,8 @@ Available fields:
58
58
  ```ts
59
59
  import { getSandbox } from 'void/sandbox';
60
60
 
61
- const sandbox = getSandbox(`user-${user.id}`);
61
+ // inside an async handler
62
+ const sandbox = await getSandbox(`user-${user.id}`);
62
63
  await sandbox.writeFile('/tmp/input.txt', 'hello');
63
64
  const result = await sandbox.exec('cat /tmp/input.txt');
64
65
  ```
@@ -10,6 +10,28 @@ Void supports framework-agnostic SSR via explicit server and client entries. Thi
10
10
  For most apps, [Pages Routing](./pages-routing/overview) handles SSR automatically. You do not need entry files or hydration code.
11
11
  :::
12
12
 
13
+ ## Relationship to Pages Routing
14
+
15
+ Custom SSR is separate from Pages Routing. Use Custom SSR when you want to bring
16
+ your own root component, router, data loading, HTML shell, and hydration logic.
17
+
18
+ The `App` component in the examples below is not a Void convention and it is not
19
+ the same thing as `pages/layout.tsx`. It is just the root component for your
20
+ custom-rendered application:
21
+
22
+ ```tsx
23
+ // src/App.tsx
24
+ export default function App({ url }: { url: string }) {
25
+ return url === '/about' ? <main>About</main> : <main>Home</main>;
26
+ }
27
+ ```
28
+
29
+ If you are using `pages/` with `@void/react`, `@void/vue`, `@void/svelte`, or
30
+ `@void/solid`, do not create `src/main.ssr.*`, `src/main.client.*`, or
31
+ `src/App.*` for Pages mode. The adapter generates the SSR and hydration entries
32
+ and automatically composes your `pages/layout.*`, route components, loaders, and
33
+ actions.
34
+
13
35
  ## Required entries
14
36
 
15
37
  SSR mode is enabled when both of these exist:
@@ -40,8 +62,9 @@ The recommended form is `defineRender(...)` for inferred types.
40
62
 
41
63
  ```ts
42
64
  {
43
- head: string; // styles/modulepreload/Vite client+preamble (dev)
44
- body: string; // main client entry script tag
65
+ css: string; // stylesheet links for <head>
66
+ preloads: string; // modulepreload/Vite client+preamble tags for <head>
67
+ body: string; // main client entry script tag before </body>
45
68
  }
46
69
  ```
47
70
 
@@ -38,7 +38,7 @@ export const GET = defineHandler(async (c) => {
38
38
 
39
39
  ### Via `cloudflare:workers` import
40
40
 
41
- When using framework mode (TanStack Start, React Router, SolidStart), the framework owns routing and you access bindings through the `cloudflare:workers` module instead:
41
+ When using framework mode (TanStack Start or React Router), the framework owns routing and you access bindings through the `cloudflare:workers` module instead:
42
42
 
43
43
  ::: warning ⚠️ Cloudflare env access in meta frameworks
44
44
  Some frameworks, like Nuxt and SvelteKit, do not run in workerd during dev and therefore do not support directly importing from `cloudflare:workers`.
@@ -91,7 +91,7 @@ This augments the `Cloudflare.Env` interface with `DB`, `KV`, `STORAGE`, `AI`, a
91
91
  | `KV` | `KVNamespace` | `env.KV` / `c.env.KV` or `import from "void/kv"` |
92
92
  | `STORAGE` | `R2Bucket` | `env.STORAGE` / `c.env.STORAGE` or `import from "void/storage"` |
93
93
  | `AI` | `Ai` | `env.AI` / `c.env.AI` or `import from "void/ai"` |
94
- | `QUEUE_*` | `Queue<T>` | `defineQueue()` or `import from "void/queue"` |
94
+ | `QUEUE_*` | `Queue<T>` | `defineQueue()` or `import { queues } from "void/queues"` |
95
95
 
96
96
  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
97
 
@@ -120,7 +120,7 @@ You can set non-binding wrangler fields like `compatibility_date` and `compatibi
120
120
  }
121
121
  ```
122
122
 
123
- For environment variables, use `.env` files instead of `worker.vars`. Void automatically loads `.env` files through Vite's `loadEnv` and merges them into the worker's `vars` bindings:
123
+ For environment variables, use `.env` files for local values and secrets. Void automatically loads `.env` files through Vite's `loadEnv` and merges them into the worker's `vars` bindings:
124
124
 
125
125
  ```bash
126
126
  # .env
@@ -129,6 +129,8 @@ API_URL=https://api.example.com
129
129
 
130
130
  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 [Wrangler config merging](#wrangler-config-merging) for details.
131
131
 
132
+ For non-secret plain-text defaults, you can also set `worker.vars` in `void.json`. Values from `.env` files override `worker.vars`.
133
+
132
134
  ## Wrangler config merging
133
135
 
134
136
  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.
@@ -57,7 +57,7 @@ Most configuration is inferred automatically. Use `void.json` to override defaul
57
57
 
58
58
  ```json
59
59
  {
60
- "$schema": "https://unpkg.com/void/schema.json",
60
+ "$schema": "./node_modules/void/schema.json",
61
61
  "inference": {
62
62
  "build": "nuxt build",
63
63
  "scanDirs": ["src", "server", "lib"],
@@ -106,18 +106,19 @@ These Void features work identically across all targets:
106
106
 
107
107
  The following imports are **not available** with a non-CF target and produce a compile-time error:
108
108
 
109
- | Import | CF Feature |
110
- | -------------- | ---------------------------- |
111
- | `void/db` | D1 (SQL database) |
112
- | `void/kv` | KV (key-value storage) |
113
- | `void/storage` | R2 (blob storage) |
114
- | `void/auth` | Void-managed Better Auth |
115
- | `void/ai` | Workers AI |
116
- | `void/env` | CF env type augmentation |
117
- | `void/ws` | Durable Objects + WebSockets |
109
+ | Import | CF Feature |
110
+ | -------------- | ------------------------ |
111
+ | `void/db` | D1 (SQL database) |
112
+ | `void/kv` | KV (key-value storage) |
113
+ | `void/storage` | R2 (blob storage) |
114
+ | `void/auth` | Void-managed Better Auth |
115
+ | `void/ai` | Workers AI |
116
+ | `void/env` | CF env type augmentation |
118
117
 
119
118
  If you need a database or storage, use an external provider and connect via standard Node.js libraries.
120
119
 
120
+ Void-managed WebSocket route files (`*.ws.ts`) are still Cloudflare-only because they compile to Durable Objects. The `void/ws` subpath is not compile-time blocked on non-CF targets, so browser-side `connect()` code can still be bundled when a WebSocket runtime is available.
121
+
121
122
  ### No cron job runtime
122
123
 
123
124
  You can still define [cron jobs](../guide/jobs.md) in `crons/` and they will compile into the bundle, but there is no built-in scheduler to invoke them. On Cloudflare, Workers Cron Triggers call the `scheduled` handler automatically. On Node.js, you'll need an external scheduler (e.g. `node-cron`, systemd timers, or your hosting platform's cron) to trigger the exported handler.
@@ -1,6 +1,6 @@
1
1
  ## Void
2
2
 
3
- This project uses [Void](https://void.cloud) — a fullstack Vite plugin + deployment platform for Cloudflare. `voidPlugin()` in `vite.config.ts` gives you file-based API routing on Hono (`routes/`), Inertia-inspired server-rendered pages with co-located loaders/actions (`pages/` + `@void/vue` or `@void/react`), auto-provisioned D1/KV/R2 bindings, first-class Drizzle ORM integration (schema in `db/schema.ts` -> `void/db` Drizzle instance -> typed routes -> typed fetch client), built-in auth, queues, cron jobs, edge caching (ISR), and one-command deploys via `npx void deploy`. For first-time setup, prefer `npx void init`; in an empty directory, install `void` first and let the interactive flow scaffold the starter, add the matching framework adapter, configure project files, handle auth, and link or create the deploy project before the first deploy. In an existing app, `void init` configures Void in place by adding missing Vite scripts and creating or patching `vite.config.*` with `voidPlugin()`. Use `void` and `@void/*` package names in source code and package manifests.
3
+ This project uses [Void](https://void.cloud) — a fullstack Vite plugin + deployment platform for Cloudflare. `voidPlugin()` in `vite.config.ts` gives you file-based API routing on Hono (`routes/`), Inertia-inspired server-rendered pages with co-located loaders/actions (`pages/` + `@void/vue` or `@void/react`), auto-provisioned D1/KV/R2 bindings, first-class Drizzle ORM integration (schema in `db/schema.ts` -> `void/db` Drizzle instance -> typed routes -> typed fetch client), built-in auth, queues, cron jobs, edge caching (ISR), and one-command deploys via `npx void deploy`. For first-time setup, prefer `npx void init`; in an empty directory, install `void` first and let the interactive flow scaffold the starter with Vite+ by default, add the matching framework adapter, configure project files, handle auth, and link or create the deploy project before the first deploy. In an existing app, `void init` configures Void in place by adding missing Vite scripts and creating or patching `vite.config.*` with `voidPlugin()`. Use `void` and `@void/*` package names in source code and package manifests.
4
4
 
5
5
  Database: define Drizzle tables in `db/schema.ts`, import `db` from `void/db` and tables from `@schema`. Use `void db push` for prototyping, `void db generate` for production migrations. `drizzle-orm` and `drizzle-kit` ship with void (no extra install). Migrations live in `db/migrations/`.
6
6
 
@@ -21,7 +21,7 @@ Install the Void CLI:
21
21
  npm install -D void
22
22
  ```
23
23
 
24
- If you run `void init` in an empty directory, the scaffold flow adds the matching Pages adapter and Vite dependencies for you.
24
+ If you run `void init` in an empty directory, the scaffold flow adds the matching Pages adapter and Vite+ by default.
25
25
 
26
26
  Then run `npx void init`. In an empty directory, the full interactive flow can scaffold a starter, configure local project files, log you in, and link or create your Void project so the next step is just `npx void deploy`. In an existing app, it configures Void in place by adding missing Vite scripts and creating or patching `vite.config.*` with `voidPlugin()`.
27
27
 
@@ -82,7 +82,7 @@ There is Vinext-specific source in the repo, but it is intentionally on hold and
82
82
 
83
83
  ## Documentation
84
84
 
85
- Full docs live at [void.cloud/docs](https://void.cloud/docs).
85
+ Full docs live at [void.cloud/guide](https://void.cloud/guide).
86
86
 
87
87
  ## License
88
88
 
@@ -13,7 +13,7 @@ Docs in this skill are bundled from `docs/` during `void` package build and live
13
13
 
14
14
  ## Command Naming
15
15
 
16
- Use `void` in examples and commands in this skill. For first-time setup, prefer `void init` followed by `void deploy`; in an empty directory, install `void` first and let `void init` add the matching Pages adapter and starter dependencies. In an existing app, `void init` configures Void in place by adding missing Vite scripts and creating or patching `vite.config.*` with `voidPlugin()`. `void init` can also handle auth and project linking interactively.
16
+ Use `void` in examples and commands in this skill. For first-time setup, prefer `void init` followed by `void deploy`; in an empty directory, install `void` first and let `void init` add the matching Pages adapter and starter dependencies with Vite+ as the default scaffold toolchain. In an existing app, `void init` configures Void in place by adding missing Vite scripts and creating or patching `vite.config.*` with `voidPlugin()`. `void init` can also handle auth and project linking interactively.
17
17
 
18
18
  Use `void` and `@void/*` in code examples and package manifests.
19
19