Astro 7 adapter for OpenWorkers.
bun add -d @openworkers/adapter-astro// astro.config.mjs
import { defineConfig } from 'astro/config';
import openworkers from '@openworkers/adapter-astro';
export default defineConfig({
output: 'server',
adapter: openworkers()
});dist/
_worker.js # The worker: one script, no imports
_routes.json # Route manifest for edge routing
assets/ # Client files and prerendered pages
The worker serves prerendered pages from the ASSETS binding and renders all other routes.
The adapter resolves cloudflare:workers to the OpenWorkers globals, so code written for Cloudflare can read its bindings:
---
import { env } from 'cloudflare:workers';
const value = await env.KV.get('key');
---Astro.locals.runtime holds env and ctx for each request. astro:env reads its variables from env.
A worker that runs in openworkers-embed has an EMBED binding. Astro.locals.invoke(command, args) calls the Rust function the host registered under that name, and returns its JSON result:
---
const user = await Astro.locals.invoke('get_user', { id: 42 });
---
<p>{user.name}</p>In an endpoint or an action, call context.locals.invoke. Extend the type of the adapter in src/env.d.ts:
import type { Locals as OpenWorkersLocals } from '@openworkers/adapter-astro';
declare global {
namespace App {
interface Locals extends OpenWorkersLocals {}
}
}
export {};A worker without an EMBED binding gets an error when it calls Astro.locals.invoke.
- The Sharp image service is a native module. When the project uses it, the adapter selects the passthrough image service, and
/_imageserves the original file. - The runtime has no Node modules. The build shows a warning when the worker imports one.
astro devandastro previewrun on Node, not on OpenWorkers.
# Create the worker and bind a storage bucket as ASSETS
ow workers create my-app
ow storage create my-storage
ow env create my-app-env
ow env bind my-app-env ASSETS my-storage --type assets
ow workers link my-app my-app-env
# Build and upload
bun run build
ow workers upload my-app ./dist