Loading...
Loading...
Framework integration for Cloudflare Workers. Use when building with Hono, Remix, Next.js, Astro, SvelteKit, Qwik, or Nuxt on Workers. Covers routing, SSR, static assets, and edge deployment.
npx skill4agent add secondsky/claude-skills workers-frameworks| Framework | Best For | SSR | Static | Workers Native |
|---|---|---|---|---|
| Hono | APIs, lightweight apps | ✅ | ✅ | ✅ Native |
| Remix | Full-stack apps | ✅ | ✅ | ✅ Adapter |
| Next.js | React apps | ✅ | ✅ | ⚠️ OpenNext |
| Astro | Content sites | ✅ | ✅ | ✅ Adapter |
| SvelteKit | Svelte apps | ✅ | ✅ | ✅ Adapter |
| Qwik | Resumable apps | ✅ | ✅ | ✅ Adapter |
| Nuxt | Vue apps | ✅ | ✅ | ✅ Nitro |
Need an API only?
└─ Yes → Hono (fastest, smallest)
└─ No → Building a full app?
└─ React → Next.js (OpenNext) or Remix
└─ Vue → Nuxt
└─ Svelte → SvelteKit
└─ Content-heavy → Astro
└─ Max performance → Qwik| Error | Framework | Cause | Solution |
|---|---|---|---|
| All | Wrong export format | Use |
| Next.js | Heavy SSR | Use ISR, reduce bundle size |
| Remix | Missing context | Pass |
| All | Node.js globals | Use |
| All | CJS in ESM | Convert to ESM imports |
| All | Body already read | Clone response before reading |
| All | Missing wrangler config | Add bindings to wrangler.jsonc |
| All | Wrong assets config | Configure |
| React/Vue | Server/client differ | Ensure consistent rendering |
| All | Circular imports | Refactor module structure |
// src/index.ts
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { logger } from 'hono/logger';
interface Env {
DB: D1Database;
KV: KVNamespace;
}
const app = new Hono<{ Bindings: Env }>();
// Middleware
app.use('*', logger());
app.use('/api/*', cors());
// Routes
app.get('/', (c) => c.text('Hello Workers!'));
app.get('/api/users', async (c) => {
const { results } = await c.env.DB.prepare('SELECT * FROM users').all();
return c.json(results);
});
app.post('/api/users', async (c) => {
const { name, email } = await c.req.json();
await c.env.DB.prepare('INSERT INTO users (name, email) VALUES (?, ?)')
.bind(name, email)
.run();
return c.json({ success: true }, 201);
});
export default app;// wrangler.jsonc
{
"name": "my-app",
"main": "src/index.ts",
"compatibility_date": "2024-12-01",
"compatibility_flags": ["nodejs_compat"],
"d1_databases": [
{ "binding": "DB", "database_name": "my-db", "database_id": "xxx" }
]
}// wrangler.jsonc - Serving static files
{
"name": "my-app",
"main": "src/index.ts",
"assets": {
"directory": "./public",
"binding": "ASSETS"
}
}// Serve static with fallback to app
import { Hono } from 'hono';
const app = new Hono<{ Bindings: { ASSETS: Fetcher } }>();
// API routes
app.get('/api/*', apiHandler);
// Static assets fallback
app.get('*', async (c) => {
return c.env.ASSETS.fetch(c.req.raw);
});
export default app;| Reference | Load When |
|---|---|
| Building APIs, microservices, or lightweight apps |
| Full-stack React with loaders/actions |
| Next.js App Router on Workers via OpenNext |
| Content sites, blogs, docs, marketing pages |
| Svelte applications on Workers |
| Resumable apps, instant loading |
| Vue 3 applications with Nitro |
// Hono
app.get('/', (c) => c.env.DB.prepare('...'));
// Remix
export async function loader({ context }) {
return context.cloudflare.env.DB.prepare('...');
}
// Astro
const db = Astro.locals.runtime.env.DB;
// SvelteKit
export async function load({ platform }) {
return platform.env.DB.prepare('...');
}
// Nuxt
const { cloudflare } = useRuntimeConfig();
// Or via nitro: event.context.cloudflare.env.DB// Universal error boundary pattern
app.onError((err, c) => {
console.error(`[${c.req.path}] ${err.message}`);
if (err instanceof HTTPException) {
return err.getResponse();
}
return c.json(
{ error: 'Internal Server Error' },
500
);
});workers-performanceworkers-runtime-apiscloudflare-worker-base