The landscape of web development has evolved significantly with the rise of edge computing and serverless architectures. In this comprehensive guide, we will explore how Astro, a modern web framework optimized for content-driven websites, pairs perfectly with Cloudflare Workers to deliver exceptional performance and developer experience.
Why Astro and Cloudflare Workers Are a Perfect Match
Astro has carved a unique niche in the web development ecosystem by prioritizing content-first architecture with minimal client-side JavaScript. This philosophy aligns perfectly with Cloudflare Workers’ edge computing model, where your code runs at over 300 data centers worldwide, bringing your application closer to users geographically.
The combination offers several compelling advantages:
- Performance by Design: Astro’s default zero-JavaScript approach means smaller bundle sizes, while Cloudflare’s global network ensures low latency delivery
- Hybrid Rendering Flexibility: Astro supports static site generation (SSG), server-side rendering (SSR), and a hybrid approach where you choose per-page rendering methods
- Cost Efficiency: Cloudflare’s generous free tier combined with Astro’s efficient architecture means you can run production applications at minimal cost
- Enhanced Security: Cloudflare provides DDoS protection, Web Application Firewall, and automatic HTTPS by default

Getting Started: Setting Up Your First Project
The fastest way to start a new Astro project with Cloudflare Workers is using the create-cloudflare CLI tool (C3). Open your terminal and run:
npm create cloudflare@latest -- my-astro-app --framework=astro
This command scaffolds a new Astro project pre-configured for Cloudflare deployment. Behind the scenes, it initializes Astro’s official setup tool and configures the necessary adapters and bindings.
Manual Configuration for Existing Projects
For existing Astro projects, you will need to add the Cloudflare adapter manually. First, install the adapter:
npx astro add cloudflare
This command installs @astrojs/cloudflare and modifies your astro.config.mjs file automatically. Add the adapter configuration:
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';
export default defineConfig({
adapter: cloudflare(),
});
Configuring Wrangler
Wrangler is Cloudflare’s CLI tool for managing Workers deployments. Create a wrangler.json (or wrangler.toml) configuration file in your project root:
{
"name": "my-astro-app",
"main": "./dist/_worker.js/index.js",
"compatibility_date": "2026-03-02",
"compatibility_flags": ["nodejs_compat"],
"assets": {
"binding": "ASSETS",
"directory": "./dist"
},
"observability": {
"enabled": true
}
}
Important Configuration Fields:
- main: Points to the Worker entry point generated by the Astro adapter
- assets.directory: Tells Wrangler where to find static assets (your built files)
- compatibility_flags:
nodejs_compatenables Node.js runtime APIs in the Worker environment - observability.enabled: Enables logging and monitoring for debugging
The .assetsignore File
Create a .assetsignore file in your public/ folder to prevent certain files from being treated as static assets:
_worker.js
_routes.json
Understanding On-Demand Rendering
Astro’s approach to rendering is flexible and powerful. By default, Astro pre-renders pages at build time (Static Site Generation). However, you can enable server-side rendering (SSR) for dynamic content.
Setting Output Mode
In your astro.config.mjs, you can control the default rendering behavior:
export default defineConfig({
output: 'server', // All pages use SSR by default
});
Alternatively, enable per-page control:
export default defineConfig({
output: 'hybrid', // Choose per page
});
Per-Page Rendering Control
For individual pages, use the prerender flag:
---
// This page will be statically generated at build time
export const prerender = true;
---
<html>
<!-- Static content -->
</html>
For server-rendered pages:
---
// This page will be rendered on each request
export const prerender = false;
---
<html>
<!-- Dynamic content -->
</html>
When to Use Each Mode:
- Static (prerender: true): Blogs, documentation, marketing pages that rarely change
- Server (prerender: false): User dashboards, personalized content, real-time data
- Hybrid: Combine both approaches in a single project for optimal performance
Accessing Cloudflare Runtime
One of the most powerful features of deploying Astro on Cloudflare Workers is access to the Cloudflare platform. This includes environment variables, D1 databases, KV namespaces, and more.
Accessing Environment Variables
In your Astro components, access the runtime through Astro.locals.runtime:
---
const { env } = Astro.locals.runtime;
const myVariable = env.MY_VARIABLE;
---
<p>Environment variable: {myVariable}</p>
Configuring Environment Variables
Add variables to your wrangler.json:
{
"vars": {
"MY_VARIABLE": "development-value"
}
}
For secrets, use the Wrangler CLI instead of committing them to configuration files:
npx wrangler secret put DB_PASSWORD
For local development, create a .dev.vars file:
DB_PASSWORD=localdevpassword
Integrating Cloudflare D1 Database
Cloudflare D1 is a serverless SQL database built on SQLite, perfect for applications that need relational data storage without managing database servers.
Creating a D1 Database
Create your first D1 database using Wrangler:
npx wrangler d1 create my-database
Note the database ID returned from this command. Add it to your wrangler.json:
{
"d1_databases": [
{
"binding": "DB",
"database_id": "your-database-id-here"
}
]
}
Accessing D1 in Your Astro Application
---
export const prerender = false;
const { env } = Astro.locals.runtime;
const result = await env.DB.prepare("SELECT * FROM users WHERE id = ?").bind(userId).first();
---
{#result ? (
<p>User: {result.username}</p>
) : (
<p>User not found</p>
)}
Using Drizzle ORM with D1
For type-safe database operations, Drizzle ORM integrates beautifully with D1:
// src/db/schema.ts
import { sqliteTable } from 'drizzle-orm/sqlite-core';
import { integer, text } from 'drizzle-orm/pg-core';
export const users = sqliteTable('users', {
id: integer('id').primaryKey(),
username: text('username').notNull(),
email: text('email').notNull().unique(),
});
Configure Drizzle in your Astro setup for seamless database operations with TypeScript type safety.

Session Management with Workers KV
Astro’s Sessions API provides a convenient way to store user data between requests. and Cloudflare KV is the perfect storage backend.
Setting Up Sessions
First, create a KV namespace:
npx wrangler kv namespace create SESSION
Add it to your wrangler.json:
{
"kv_namespaces": [
{
"binding": "SESSION",
"id": "your-kv-namespace-id"
}
]
}
Using Sessions in Your Application
---
export const prerender = false;
const cart = await Astro.session?.get('cart');
---
<a href="/checkout">
Cart ({cart?.length ?? 0} items)
</a>
Sessions automatically use the KV namespace configured in your wrangler file. The default binding name is SESSION, but you can customize this with the sessionKVBindingName adapter option.

Image Optimization with Cloudflare Images
The Astro Cloudflare adapter provides multiple image service options for optimal performance.
Available Image Services
- cloudflare: Uses Cloudflare Image Resizing service for on-the-fly image optimization
- passthrough: Disables image optimization (useful for images already optimized)
- compile: Uses Astro’s default sharp service at build time only
Configure the image service in your adapter:
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';
export default defineConfig({
adapter: cloudflare({
imageService: 'cloudflare'
}),
});
The Cloudflare image service automatically optimizes images served through your application, resizing and converting formats based on client capabilities.
Development and Deployment Workflow
Local Development
Start your development server with:
npm run dev
For Wrangler-based local development with access to bindings:
"preview": "wrangler dev"
Building for Production
Build your application:
npm run build
This generates:
- Static assets in
./dist - Worker script at
./dist/_worker.js/index.js
Deploying to Cloudflare
Deploy your application:
npm run deploy
Or manually:
npx astro build
npx wrangler deploy
Previewing Production Builds
For a production-like preview using Wrangler:
npx wrangler dev
Node.js Compatibility
Cloudflare Workers does not support the full Node.js runtime by default. However, many Node.js APIs are available through the nodejs_compat compatibility flag.
Enabling Node.js Compatibility
The flag is already included in our recommended wrangler configuration. This enables:
node:bufferfor Buffer operationsnode:cryptofor cryptographic functionsnode:utilfor utility functions
Using Node.js APIs in Astro
---
export const prerender = false;
import { Buffer } from 'node:buffer';
---
<script>
const buffer = Buffer.from('Hello, World!');
</script>
Note that pages using Node.js APIs must have export const prerender = false to enable server-side rendering.
Custom Error Pages
Serve custom 404 pages by configuring your wrangler file:
{
"assets": {
"directory": "./dist",
"not_found_handling": "404-page"
}
}
This serves your src/pages/404.astro file when a route is not found.
Troubleshooting Common Issues
Build Errors
Problem: Build fails with “Cannot find module” errors
Solution: Ensure all dependencies are installed and your wrangler configuration is correct. Run npm install to verify all packages are present.
Runtime Errors
Problem: “X is not a function” errors in components
Solution: This typically means a component is not interactive when it should be. Ensure you have added the appropriate client:* directive to your React component in Astro templates.
Environment Variable Issues
Problem: Environment variables are undefined
Solution: Verify your .dev.vars file for local development or your secrets configuration for production. Ensure variable names match exactly between configuration and usage.
Session Problems
Problem: Sessions are not persisting
Solution: Verify your KV namespace is correctly configured and the binding name matches between your wrangler configuration and adapter settings.
Best Practices
1. Use Hybrid Rendering Wisely
Not every page needs server-side rendering. Static pages like About, Privacy Policy, and documentation should be pre-rendered for optimal performance. Reserve SSR for pages that truly need dynamic content.
2. Leverage Edge Caching
Cloudflare’s edge network provides automatic caching for static assets. Structure your application to maximize cache hits by keeping dynamic data in clearly defined API endpoints.
3. Monitor Your Application
Enable observability in your wrangler configuration for insights into your application’s performance and errors.
4. Keep Wrangler Updated
Cloudflare frequently updates Wrangler with new features and bug fixes. Keep your local installation current
npm install wrangler@latest
5. Test Locally with Bindings
Use wrangler dev for local development when testing D1 databases, KV namespaces, or other bindings. The standard Astro dev server does not have access to these Cloudflare-specific features.
The Future: Astro 6 and Beyond
Astro 6, currently in beta as of early 2026, introduces even tighter integration with Cloudflare Workers through Vite’s Environment API. This update brings:
- Redesigned Development Server: Better hot module replacement and faster rebuilds
- First-Class Cloudflare Support: Native integration without requiring adapter configuration in many cases
- Improved Build Performance: Leveraging Vite 6’s enhanced build capabilities
If you are starting a new project, consider trying the Astro 6 beta to experience these improvements. For existing projects, the upgrade path will be straightforward when Astro 6 reaches stable release.
Conclusion
Building web applications with Astro and Cloudflare Workers combines the best of modern web development: Astro’s excellent developer experience and content-first architecture with Cloudflare’s global edge network and serverless platform. The combination enables you to build fast, secure, and cost-effective applications that scale automatically with your traffic.
Whether you are building a blog, an e-commerce platform, or a complex web application, this stack provides the tools and infrastructure to deliver exceptional user experiences. Start with the create-cloudflare CLI for quick setup, or migrate existing projects using the adapter configuration outlined in this guide.
The edge computing revolution is here, and with Astro and Cloudflare Workers, you are well-equipped to build the next generation of web applications.
Next Steps
- Explore the Astro documentation for framework-specific guides
- Dive into Cloudflare Workers docs for platform details
- Check out Astro Cloudflare adapter documentation for advanced configuration
- Join the Astro Discord community for support and discussions
- Follow @CloudflareDev on Twitter for platform updates




