Astro
Add the SDK to an Astro app to get resource detection, typed database queries and migrations. Astro keeps its own build and Cloudflare integration. The SDK plugs into its Vite config.
On this pageSet up the SDK in an Astro project · Use SDK features such as void/db from Astro · Reach Cloudflare bindings directly when you need them
Astro 6 required
import { x } from "void/x"helpers need Astro 6+.- Enable
"nodejs_als"undercompatibility_flagsin your Cloudflare config.
Setup
Follow these steps in order.
1. Create a new project
Now you will create a new app and open the new app folder.
npm create astro@latest my-app
cd my-appExample output: the scaffolder asks a few questions and creates the app folder.
2. Install dependencies
Now you will install the dependencies.
npm install -D @astrojs/cloudflare voidExample output: npm finishes with added N packages and no errors.
3. 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
This step adds the config that the Cloudflare adapter uses in dev and deploy:
import { defineConfig } from 'void/config';
export default defineConfig({
cloudflare: {
name: 'my-app',
compatibility_date: '2026-02-24',
compatibility_flags: ['nodejs_als'],
},
});The void/* runtime helpers, such as void/db and void/kv, need nodejs_als in Astro.
5. Deploy
Requires: login to your deploy target
void auth login opens your browser to sign in to Cloudflare or your team's platform. No token goes in your project.
Now you will sign in and deploy the app.
void auth login
void deployExample output: A browser window opens. The CLI confirms the sign-in when you finish. Build and upload progress, then the live URL.
Use SDK features
Most SDK platform features work with Astro in local dev and production. You need Astro 6+ with nodejs_als.
Framework mode does not support SDK-managed auth yet. Use Better Auth's official Astro integration for now.
Pages that read runtime bindings must turn off prerendering:
---
export const prerender = false;
// now Astro.locals.runtime is available
---Database
Use void/db in API routes and other server-side code:
import { users } from '@schema';
import type { APIRoute } from 'astro';
import { db } from 'void/db';
export const GET: APIRoute = async () => {
const rows = await db.select().from(users);
return Response.json(rows);
};Other resources
Use KV, object storage and AI in server-side code. The imports are the same as in an SDK app. Add cron jobs in crons/ and queue consumers in queues/.
Environment variables
Declare variables in env.ts. Read them with import { env } from "void/env". See Environment Variables for local values, production secrets and public VITE_* values.
The SDK always uses VITE_* for schema keys exposed to the client, in Astro too. Astro's PUBLIC_* convention still applies to direct import.meta.env access. It does not change the void/env server and client boundary.
For environment variables, void/env replaces astro:env and Astro.locals.runtime.env. Keep Astro.locals.runtime.env for raw binding access, such as D1, KV or R2.
Access bindings directly
Read bindings from Astro.locals.runtime.env. This works in dev and production:
import type { APIRoute } from 'astro';
export const GET: APIRoute = async ({ locals }) => {
const { DB } = locals.runtime.env;
const { results } = await DB.prepare('SELECT * FROM users').all();
return Response.json(results);
};In .astro pages, set prerender = false first:
---
export const prerender = false;
const { DB } = Astro.locals.runtime.env;
const { results } = await DB.prepare("SELECT * FROM users").all();
---