Skip to content
brought to you byVoidZero

Supported App Types ​

Void supports three types of apps:

  1. Void apps: Vite apps powered by Void's framework layer, including API routes, pages mode, auth, crons, and queues
  2. Meta frameworks: TanStack Start, React Router, SvelteKit, Nuxt, and Astro
  3. Static sites: SPAs, sites built with tools like VitePress, or any directory of static files

The type is auto-detected from your project structure, or you can set it explicitly in void.json.

Void Apps ​

In a Void app, Void handles server routing and deployment. Use React, Vue, Svelte, or Solid for server-rendered pages, or build a frontend with any library that works with Vite.

All Void features that involve backend logic are available in this mode, including server routing, pages mode, authentication, typed fetch, cron jobs, and queues.

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):

  • pages/Server-rendered pages
    • index.tsx
    • users/
      • [id].tsx
      • [id].server.ts
  • routes/API endpoints
    • api/
      • hello.ts
  • vite.config.ts
  • void.json

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

Void apps can also use output: 'static' 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 the app, provisions resources, applies migrations, and uploads it to your saved Cloudflare or Void target. See Deployment for setup.

Detected when any of these exist:

  • routes/ directory
  • pages/ directory
  • middleware/ directory
  • crons/ directory
  • queues/ directory
  • Custom SSR entry (src/main.ssr.ts or src/main.ssr.tsx)

Meta Frameworks ​

Void supports deploying Vite-based meta-framework apps with void deploy. The framework owns routing and SSR. Void handles binding inference, typed DB queries, migrations, and deployment.

FrameworkDetected from packageSetup guide
TanStack Start@tanstack/react-startGuide
React Router v7@react-router/devGuide
SvelteKit@sveltejs/kitGuide
NuxtnuxtGuide
Analog@analogjs/platformGuide
AstroastroGuide

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 for the full feature matrix, deploy pipeline, and per-framework setup guides.

Deploy: void deploy runs your framework's build, provisions resources, applies migrations, and deploys to the selected target. Your framework continues to handle routing and rendering.

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

Pre-built Static Sites ​

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.

Static sites (static site generators like VitePress, Docusaurus, or any pre-built directory) produce per-page HTML files. Detected when a known SSG is a dependency, or when using the --dir flag.

At the edge, the resolution order is:

  1. Exact file path (/styles.css → styles.css)
  2. Nested index (/about → about/index.html)
  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. Assets are served from the edge with automatic caching.

Adding a backend to a static site ​

If you add API routes to a static site generator, tell Void whether to deploy the backend too. Auto-detection sees both the SSG dependency and backend files, and stops until you set inference.appType.

To deploy both, set appType to "void" and build the static site before the Void app:

json
// void.json
{
  "inference": {
    "appType": "void",
    "build": "vitepress build && vite build"
  }
}
ts
// vite.config.ts
import { defineConfig } from 'vite';
import { voidPlugin } from 'void';

export default defineConfig({
  plugins: [voidPlugin()],
  // The SSG's output becomes the static assets of the Void build.
  publicDir: '.vitepress/dist',
});

vitepress build emits the site, then vite build copies publicDir into dist/client and emits the worker into dist/ssr. Keep voidPlugin() in the root vite.config.ts only — not in the generator's own config (e.g. .vitepress/config.ts).

Because the worker now owns unmatched requests, add routing.notFound if you want the generator's 404.html instead of the SPA-style index.html fallback:

json
{ "routing": { "notFound": "404-page" } }

To deploy only the static output, set:

json
{ "inference": { "appType": "static" } }

Auto-Detection ​

When running void deploy and no inference.appType is set in void.json, the detection logic runs in this order:

PriorityConditionType
1--dir flagStatic (or SPA with --spa)
2Known SSG in dependencies (vitepress, @docusaurus/core)Static, builds with SSG CLI
2a...and backend files also existRefused — set inference.appType yourself
3@tanstack/react-start, @react-router/dev, @sveltejs/kit, nuxt, @analogjs/platform, or astro in depsFramework
4Backend files exist (routes/, pages/, middleware/, crons/, queues/, SSR entry)Void app
5vite or vite-plus in dependencies, no backend filesSPA, builds with vite build or vp build
6dist/index.html or ./index.html existsStatic (no build step)

Explicit Configuration ​

To lock the app type and skip auto-detection, set inference.appType in void.json:

json
{
  "inference": {
    "appType": "static",
    "outputDir": ".vitepress/dist"
  }
}
  • inference.appType: "void", "framework", "spa", or "static"
  • inference.outputDir: output directory for static app types (relative to project root, defaults to "dist")