Astro
Use Void with Astro for resource detection, typed database queries, and migrations. Astro keeps its own build and Cloudflare integration; Void plugs into its Vite configuration.
Astro 7 required
- Astro 7+ is required because Void needs Vite 8.
- You also need to enable
"nodejs_als"undercompatibility_flagsin your Cloudflare config.
Setup
1. Create a new project
npm create astro@latest my-app
cd my-app2. Install dependencies
npm install -D @astrojs/cloudflare void3. Configure astro.config.mjs
import cloudflare from '@astrojs/cloudflare';
import { defineConfig } from 'astro/config';
import { voidPlugin } from 'void';
export default defineConfig({
adapter: cloudflare({ configPath: './.void-wrangler.jsonc' }),
vite: { plugins: [voidPlugin()] },
});4. Create void.config.ts
Void uses this config for the Cloudflare adapter during development and deployment:
import { defineConfig } from 'void/config';
export default defineConfig({
cloudflare: {
name: 'my-app',
compatibility_date: '2026-02-24',
compatibility_flags: ['nodejs_als'],
},
});nodejs_als is required for void/* runtime helpers (for example void/db, void/kv) in Astro.
5. Deploy
void auth login
void deployUsing Void Features
Most Void platform features work with Astro in both local dev and production when using Astro 7+ with nodejs_als.
Void-managed auth is not supported in framework mode yet. Use Better Auth's official Astro integration directly for now.
Pages and API routes that access runtime bindings must opt out of prerendering:
---
export const prerender = false;
---Database
Use void/db in API routes and server-side code:
import { users } from '@schema';
import type { APIRoute } from 'astro';
import { db } from 'void/db';
export const prerender = false;
export const GET: APIRoute = async () => {
const rows = await db.select().from(users);
return Response.json(rows);
};Other resources
Use KV, object storage, and AI from server-side code with the same imports as a Void app. Add cron jobs in crons/ and queue consumers in queues/.
Environment Variables
Declare variables in env.ts and read them with import { env } from "void/env". See Environment Variables for local values, production secrets, and public VITE_* values.
Void always uses VITE_* for client-exposed schema keys, including in Astro projects. Astro's separate PUBLIC_* convention still applies to direct import.meta.env access, but it does not change the void/env server/client boundary.
void/env replaces astro:env for env-var access. Use env from cloudflare:workers when you need raw binding access (D1, KV, R2, etc.).
Accessing Bindings Directly
Access bindings with env from cloudflare:workers (works in both dev and production):
import type { APIRoute } from 'astro';
import { env } from 'cloudflare:workers';
export const prerender = false;
export const GET: APIRoute = async () => {
const { results } = await env.DB.prepare('SELECT * FROM users').all();
return Response.json(results);
};In .astro pages (remember to set prerender = false):
---
import { env } from 'cloudflare:workers';
export const prerender = false;
const { results } = await env.DB.prepare("SELECT * FROM users").all();
---