Skip to content
Built with

Supported app types ​

Start

Before you start, pick the shape of your app. The SDK supports three: SDK apps, meta-framework apps, and pre-built static sites.

On this pageChoose between an SDK app, a meta-framework or a static site · Add a backend to an existing static site · Set the app type yourself when auto-detection can't decide

  1. SDK apps: Vite apps powered by the SDK'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.config.ts.

SDK apps ​

In an SDK app, the SDK 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.

An SDK 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

The SDK serves API routes, page rendering, and optional custom SSR alongside static assets. Resources such as D1, KV, and R2 are inferred from your code and provisioned when you deploy.

SDK 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 SDK platform target. See Deployment for setup.

Meta-frameworks ​

The SDK supports deploying Vite-based meta-framework apps with void deploy. The framework owns routing and SSR. The SDK 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. SDK-managed auth is not supported in framework mode; use Better Auth's official integration for your framework. See the Meta Frameworks Integration for supported features and setup guides.

Pre-built static sites ​

Any project that produces static files, whether that is an SPA, a static site, or a plain directory. The SDK serves the assets without requiring application code.

SPAs (client-side single-page apps) serve index.html with a 200 status for paths that match no file, so client-side routing works out of the box. On an SDK platform, missing files under the hashed assets folder (/assets/) return 404 instead. 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.

Add a backend to a static site ​

Now you'll tell the SDK how to deploy a static site that also has API routes.

Auto-detection finds both a static site generator and backend files. It stops until you set inference.appType.

To deploy both, set appType to "void". Build the static site first, then the SDK app.

ts
import { defineConfig } from 'void/config';

export default defineConfig({
  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 writes the site. vite build then copies publicDir into dist/client and writes the Worker into dist/ssr.

Keep voidPlugin() in the root vite.config.ts only. Don't add it to the generator's own config, such as .vitepress/config.ts.

The Worker answers requests that match no file. To serve the generator's 404.html for them, set routing.notFound.

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

To deploy only the static output, use this instead.

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

Set the app type yourself ​

Now you'll lock the app type so auto-detection is skipped.

Set inference.appType in void.config.ts.

json
{
  "inference": {
    "appType": "static",
    "outputDir": ".vitepress/dist"
  }
}
  • inference.appType: "void", "framework", "spa" or "static".
  • inference.outputDir: the output folder for static types. It is relative to the project root. The default is "dist".

Next steps ​

implemented.stream AI