Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 15 additions & 27 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,29 +91,20 @@ const integrationLinks = {
items: integrationItems,
};

const resourcesLinks = {
text: "Resources",
items: [
{ text: "Recipes", link: "/recipes/", activeMatch: "/recipes/" },
{ text: "Examples", link: "/examples/", activeMatch: "/examples/" },
{ text: "Roadmap", link: "/roadmap/", activeMatch: "/roadmap/" },
{ text: "Blog", link: "https://voidzero.dev/blog" },
],
};

const socialLinks = [
{ icon: "x", link: "https://x.com/voidcloudhq" },
{ icon: "discord", link: "https://discord.gg/cC6TEVFKSx" },
{ icon: "github", link: "https://github.com/voidzero-dev/void" },
];

const platformLinks = {
text: "Platform",
const companyLinks = {
text: "Company",
items: [
{ text: "Company", link: "https://voidzero.dev" },
{ text: "Features", link: "/platform/features" },
{ text: "Pricing", link: "/platform/pricing" },
{ text: "Enterprise", link: "/platform/enterprise" },
{ text: "Blog", link: "https://voidzero.dev/blog" },
{ text: "Terms of Service", link: "https://voidzero.dev/legal/terms" },
{ text: "Privacy Policy", link: "https://voidzero.dev/legal/privacy" },
{ text: "Acceptable Use Policy", link: "https://voidzero.dev/legal/acceptable-use" },
],
};

Expand Down Expand Up @@ -147,8 +138,6 @@ export default extendConfig(
{ text: "Guide", link: "/guide/", activeMatch: "/guide/" },
referenceLinks,
integrationLinks,
// resourcesLinks,
// platformLinks,
// { text: "Dashboard", link: "https://dash.void.cloud" },
],

Expand Down Expand Up @@ -301,19 +290,18 @@ export default extendConfig(
],
},
{
title: "Resources",
items: resourcesLinks.items,
},
{
title: "Platform",
title: "Open Source",
items: [
...platformLinks.items,
// {
// text: "Dashboard",
// link: "https://dash.void.cloud",
// },
{ text: "Vite", link: "https://vite.dev" },
{ text: "Vitest", link: "https://vitest.dev" },
{ text: "Rolldown", link: "https://rolldown.rs" },
{ text: "Oxc", link: "https://oxc.rs" },
],
},
{
title: companyLinks.text,
items: companyLinks.items,
},
],
social: socialLinks,
},
Expand Down
16 changes: 8 additions & 8 deletions docs/guide/ai.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ outline: deep

# AI

Void provides a typed AI client powered by Cloudflare's [AI Gateway](https://developers.cloudflare.com/ai-gateway/), supporting both [Workers AI](https://developers.cloudflare.com/workers-ai/) models and third-party providers (OpenAI, Anthropic, Google, etc.) via bring-your-own-key. Import `ai` from `void/ai` and run inference models directly from your route handlers — all usage is metered via Void.
Void provides a typed AI client powered by Cloudflare's [AI Gateway](https://developers.cloudflare.com/ai-gateway/). It supports both [Workers AI](https://developers.cloudflare.com/workers-ai/) models and third-party providers such as OpenAI, Anthropic, and Google through bring-your-own-key credentials. Import `ai` from `void/ai` and run inference directly from your route handlers. Usage is metered through Void.

```ts
import { ai } from "void/ai";
Expand All @@ -29,11 +29,11 @@ export const POST = defineHandler(async (c) => {
});
```

You can use any model available on [Workers AI](https://developers.cloudflare.com/workers-ai/models/) — text generation, image classification, embeddings, translation, and more.
You can use any model available on [Workers AI](https://developers.cloudflare.com/workers-ai/models/), including text generation, image classification, embeddings, translation, and more.

## Streaming

Use `ai.stream()` to get a streaming response with SSE headers — ready to return directly from a route handler:
Use `ai.stream()` to get a streaming response with SSE headers that you can return directly from a route handler:

```ts
import { defineHandler } from "void";
Expand Down Expand Up @@ -73,11 +73,11 @@ const result = await ai.toMarkdown([{ name: "document.pdf", blob: pdfBytes }]);

AI requires Void credentials for local development. Run `void auth login` and `void project link` (or follow the interactive setup during `vite dev`) to connect your project.

Once linked, credentials are injected automatically as worker bindings — no manual configuration needed. All inference traffic routes through the Void AI proxy over HTTPS, so usage is tracked and metered the same way as in production.
Once linked, credentials are injected automatically as worker bindings. You do not need to configure them by hand. All inference traffic goes through the Void AI proxy over HTTPS, so usage is tracked and metered the same way it is in production.

## Usage Limits

Workers AI usage is metered in [**neurons**](https://developers.cloudflare.com/workers-ai/platform/pricing/) — Cloudflare's unit for inference cost. Usage resets at the start of each billing cycle.
Workers AI usage is metered in [**neurons**](https://developers.cloudflare.com/workers-ai/platform/pricing/), which is Cloudflare's unit for inference cost. Usage resets at the start of each billing cycle.

| Plan | Included | At limit |
| ---- | ------------- | ---------------------------------- |
Expand All @@ -89,7 +89,7 @@ On the **free tier**, AI requests return a `429` error once the limit is reached

## Third-Party Providers (BYOK)

You can use models from OpenAI, Anthropic, Google, and other providers by passing a `provider/model` identifier. Bring your own API key — add it as a project secret, and Void handles the rest. Third-party inference is billed directly by the provider — Void does not mark up API calls. All requests still route through AI Gateway for usage tracking on the dashboard.
You can use models from OpenAI, Anthropic, Google, and other providers by passing a `provider/model` identifier. Bring your own API key, add it as a project secret, and Void handles the rest. Third-party inference is billed directly by the provider, and Void does not mark up API calls. Requests still route through AI Gateway so usage shows up on the dashboard.

### Usage

Expand All @@ -111,7 +111,7 @@ export const POST = defineHandler(async (c) => {

The same `ai.run()` and `ai.stream()` methods work for both Workers AI and third-party models. The framework detects the provider from the model string and routes the request through [AI Gateway](https://developers.cloudflare.com/ai-gateway/) automatically.

The options follow each provider's conventions — all third-party providers use the OpenAI-compatible chat completions format (`messages`, `max_tokens`, `temperature`, etc.). TypeScript narrows the input and return types based on the model string: Workers AI models get per-model typed inputs from `@cloudflare/workers-types`, while third-party models (`"provider/model"`) get `ChatCompletionInputs` and `ChatCompletionResponse`.
The options follow each provider's conventions. All third-party providers use the OpenAI-compatible chat completions format, including `messages`, `max_tokens`, and `temperature`. TypeScript narrows the input and return types based on the model string: Workers AI models get per-model typed inputs from `@cloudflare/workers-types`, while third-party models such as `"provider/model"` get `ChatCompletionInputs` and `ChatCompletionResponse`.

### Provider Key Convention

Expand Down Expand Up @@ -158,7 +158,7 @@ If the key is missing at runtime, `ai.run()` throws a descriptive error telling

### Streaming with Third-Party Models

`ai.stream()` works the same way — the response is always SSE regardless of provider:
`ai.stream()` works the same way. The response is always SSE regardless of provider:

```ts
export const POST = defineHandler(async (c) => {
Expand Down
20 changes: 10 additions & 10 deletions docs/guide/app-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,25 @@ outline: deep

Void supports three types of apps:

1. **Void apps** — Vite apps powered by Void's framework layer ([API routes](./server-routing.md), [pages mode](./pages-routing/overview.md), [auth](./auth.md), [crons](./jobs.md), [queues](./queues.md))
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/), [Astro](https://astro.build/)
3. **Static sites** — SPAs, static sites like [VitePress](https://vitepress.dev/), or any directory of static files
1. **Void apps:** Vite apps powered by Void's framework layer, including [API routes](./server-routing.md), [pages mode](./pages-routing/overview.md), [auth](./auth.md), [crons](./jobs.md), and [queues](./queues.md)
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/)
3. **Static sites:** SPAs, sites built with tools like [VitePress](https://vitepress.dev/), or any directory of static files

The type is auto-detected from your project structure, or you can set it explicitly in [`void.json`](../reference/config.md).

## Void Apps

A Vite app powered by Void's framework layer. In this mode, **Void is both the framework and the platform** — an opinionated setup that unlocks DX perks unique to Void, while staying frontend-framework-agnostic. You can use it with React, Vue, Svelte, Solid, or any frontend that works with Vite.
A Vite app powered by Void's framework layer. In this mode, **Void is both the framework and the platform**. It is opinionated in the backend and deployment story, while still staying frontend-framework-agnostic. You can use it with React, Vue, Svelte, Solid, or any frontend that works with Vite.

All Void features that involve backend logic — [server routing](./server-routing.md), [pages mode](./pages-routing/overview.md), [authentication](./auth.md), [typed fetch](./typed-fetch.md), [cron jobs](./jobs.md), [queues](./queues.md) — are available in this mode.
All Void features that involve backend logic are available in this mode, including [server routing](./server-routing.md), [pages mode](./pages-routing/overview.md), [authentication](./auth.md), [typed fetch](./typed-fetch.md), [cron jobs](./jobs.md), and [queues](./queues.md).

A Void app can be **API-only** (just `routes/`), a **SPA + API** (frontend in `src/` with API routes), or **full-stack with pages mode** (server-rendered pages in `pages/` with co-located data loading):

<VoidAppFileTree annotations />

Your worker handles API routes, page rendering, and (optionally) [custom SSR](./ssr.md). Static assets are served from the edge via per-worker assets. Cloudflare bindings (D1, KV, R2) are [inferred from your source code](../reference/resource-inference.md) and provisioned automatically.

Void apps can also be configured with [`output: 'static'`](./ssg.md) to pre-render all pages at build time, producing a fully static site that can be deployed anywhere — no Cloudflare Workers required.
Void apps can also use [`output: 'static'`](./ssg.md) to pre-render all pages at build time. That gives you a fully static site that can be deployed anywhere, with no Cloudflare Worker required.

**Deploy:** `void deploy` builds via Vite, infers bindings, provisions D1/KV/R2 resources, applies migrations, uploads assets and worker, and makes the site live at `{slug}.void.app`. See [Deployment](./deployment.md) for details.

Expand All @@ -39,7 +39,7 @@ Void apps can also be configured with [`output: 'static'`](./ssg.md) to pre-rend

## Meta Frameworks

Void supports deploying Vite-based meta-framework apps via `void deploy`. The framework owns routing and SSR — Void handles [binding inference](../reference/resource-inference.md), [typed DB queries](./database.md), migrations, and deployment.
Void supports deploying Vite-based meta-framework apps with `void deploy`. The framework owns routing and SSR. Void handles [binding inference](../reference/resource-inference.md), [typed DB queries](./database.md), migrations, and deployment.

| Framework | Detected from package | Setup guide |
| --------------------------------------------------- | ----------------------- | ----------------------------------------------------- |
Expand All @@ -51,13 +51,13 @@ Void supports deploying Vite-based meta-framework apps via `void deploy`. The fr

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.

**Deploy:** `void deploy` runs the framework's build, packages the output, and deploys to Void. The framework owns routing and SSR — Void handles resource provisioning, migrations, and edge hosting.
**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.

**Detected when** any of the above packages is in your dependencies.

## Pre-built Static Sites

Any project that produces static files — SPAs, static sites, or plain directories. Assets are served directly from the edge. A minimal passthrough worker is generated automatically — no user code is needed.
Any project that produces static files, whether that is an SPA, a static site, or a plain directory. Assets are served directly from the edge, and a minimal passthrough worker is generated automatically. You do not need to write worker code yourself.

**SPAs** (client-side single-page apps) fall back all non-file paths to `index.html` with a 200 status, so client-side routing works out of the box. Detected when `vite` is a dependency and no backend files exist.

Expand All @@ -70,7 +70,7 @@ At the edge, the resolution order is:
3. `404.html` with **status 404** (if the file exists)
4. Plain 404 response

**Deploy:** `void deploy` (or `void deploy --dir <path>`) uploads static files directly — no worker code needed. Assets are served from the edge with automatic caching.
**Deploy:** `void deploy` or `void deploy --dir <path>` uploads static files directly. Assets are served from the edge with automatic caching.

## Auto-Detection

Expand Down
2 changes: 1 addition & 1 deletion docs/guide/auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Add a provider to `void.json`. Email/password is the default, so the simplest co
}
```

You can also skip this step entirely — auth activates automatically when you import from `void/auth` or `void/client`.
You can also skip this step entirely. Auth activates automatically when you import from `void/auth` or `void/client`.

### 2. Sign up and sign in

Expand Down
26 changes: 13 additions & 13 deletions docs/guide/database.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const dbFileItems = [

# Database

Void provides a first-class [Drizzle ORM](https://orm.drizzle.team) integration. Define your schema as TypeScript, import a pre-wired Drizzle instance from `void/db`, and start querying — no extra install needed.
Void provides a first-class [Drizzle ORM](https://orm.drizzle.team) integration. Define your schema in TypeScript, import the pre-wired Drizzle instance from `void/db`, and start querying. You do not need an extra install.

<FileTree :items="dbFileItems" default-expanded />

Expand Down Expand Up @@ -86,7 +86,7 @@ export const users = pgTable("users", {

:::

Everything ships with `void` — there is nothing extra to install. You don't have to write this by hand — use `void gen model` or let your coding agent generate it.
Everything ships with `void`, so there is nothing extra to install. You also do not have to write this by hand. Use `void gen model` or let your coding agent generate it.

You can also split your schema across multiple files under `db/schema/` and re-export from a barrel file:

Expand All @@ -112,7 +112,7 @@ import { users } from "@schema";
```

::: info What is `@schema`?
`@schema` is a Vite path alias that the Void plugin configures automatically to point to your `db/schema.ts` file (or `db/schema/` directory). You don't need to set it up — just use it to import your table definitions.
`@schema` is a Vite path alias that the Void plugin configures automatically. It points to your `db/schema.ts` file, or `db/schema/` if you split tables across files. You can just use it to import table definitions.
:::

### List rows
Expand Down Expand Up @@ -301,7 +301,7 @@ export const insertUserSchema = createInsertSchema(users, {

:::

`createInsertSchema` generates a validator that matches `$inferInsert` — columns with defaults or auto-increments become optional, `NOT NULL` columns are required. The optional second argument refines individual columns — either via a callback that receives the auto-generated schema, or by passing a type directly to override the field.
`createInsertSchema` generates a validator that matches `$inferInsert`. Columns with defaults or auto-increments become optional, while `NOT NULL` columns stay required. The optional second argument lets you refine individual columns, either with a callback that receives the generated schema or by passing a type directly to override a field.

Use the derived schema in your route handlers with [`withValidator()`](./server-routing.md#validation):

Expand All @@ -321,11 +321,11 @@ export const POST = defineHandler.withValidator({

Three functions are available:

| Function | Purpose |
| -------------------- | ------------------------------------------------------------------------- |
| `createInsertSchema` | Validates insert data — excludes auto-generated columns, applies defaults |
| `createSelectSchema` | Matches the shape of selected rows |
| `createUpdateSchema` | Like insert but all fields are optional (partial update) |
| Function | Purpose |
| -------------------- | ----------------------------------------------------------------------------- |
| `createInsertSchema` | Validates insert data, excluding auto-generated columns and applying defaults |
| `createSelectSchema` | Matches the shape of selected rows |
| `createUpdateSchema` | Like insert but all fields are optional (partial update) |

Void already bundles the Drizzle adapters. Install the validator library itself if you use its direct APIs in your schema file:

Expand Down Expand Up @@ -356,17 +356,17 @@ See the [CLI reference](../reference/cli.md#database) for details.

## Scaffolding

The `void gen model` command scaffolds a Drizzle table definition and updates your barrel export. It generates dialect-appropriate code — `sqliteTable` for D1, `pgTable` for PostgreSQL:
The `void gen model` command scaffolds a Drizzle table definition and updates your barrel export. It generates dialect-appropriate code: `sqliteTable` for D1 and `pgTable` for PostgreSQL.

```bash
void gen model post title:string body:text published:boolean
```

This creates:

1. `db/schema/post.ts` — a Drizzle table definition with `id`, `createdAt`, `updatedAt`, and your columns
1. `db/schema/post.ts`: a Drizzle table definition with `id`, `createdAt`, `updatedAt`, and your columns
2. Updates `db/schema.ts` with `export * from "./schema/post"`
3. `routes/api/posts/index.ts` — GET (list) + POST (insert with validation)
4. `routes/api/posts/[id].ts` — GET by id with 404 handling
3. `routes/api/posts/index.ts`: `GET` for list and `POST` for insert with validation
4. `routes/api/posts/[id].ts`: `GET` by id with `404` handling

See the [CLI reference](../reference/cli.md#code-generation) for the full list of generators.
Loading
Loading