mcpbeat

Cloudflare Workers Frameworks

secondsky/cloudflare-workers-frameworks

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.

This is a copy. The original lives at comeonoliver/cloudflare-workers-frameworks.

40k tokens
context cost
the whole folder, loaded on every use
15
files
ships runnable scripts
0
copies elsewhere
how many repositories repackaged it
202
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/secondsky/claude-skills --skill cloudflare-workers-frameworks

The instruction itself

12 sections, as written by the author

Workers Frameworks Integration

Build full-stack applications on Cloudflare Workers using modern frameworks.

Quick Start: Choose Your Framework

| 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 |

Framework Decision Tree

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

Top 10 Framework Errors

| Error | Framework | Cause | Solution |

|-------|-----------|-------|----------|

| No matching export "default" | All | Wrong export format | Use export default app not module.exports |

| Worker exceeded CPU limit | Next.js | Heavy SSR | Use ISR, reduce bundle size |

| Cannot read properties of undefined (reading 'env') | Remix | Missing context | Pass context to loader/action |

| globalThis is not defined | All | Node.js globals | Use nodejs_compat flag |

| Dynamic require not supported | All | CJS in ESM | Convert to ESM imports |

| Response body is locked | All | Body already read | Clone response before reading |

| Bindings not available | All | Missing wrangler config | Add bindings to wrangler.jsonc |

| 404 on static assets | All | Wrong assets config | Configure assets in wrangler.jsonc |

| Hydration mismatch | React/Vue | Server/client differ | Ensure consistent rendering |

| Maximum call stack exceeded | 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" }
  ]
}

Static Assets Configuration

// 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;

When to Load References

Load the specific framework reference when user:

| Reference | Load When |

|-----------|-----------|

| references/hono.md | Building APIs, microservices, or lightweight apps |

| references/remix.md | Full-stack React with loaders/actions |

| references/nextjs.md | Next.js App Router on Workers via OpenNext |

| references/astro.md | Content sites, blogs, docs, marketing pages |

| references/sveltekit.md | Svelte applications on Workers |

| references/qwik.md | Resumable apps, instant loading |

| references/nuxt.md | Vue 3 applications with Nitro |

Common Patterns Across Frameworks

Environment Bindings Access

// 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

Error Handling Pattern

// 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
  );
});

Performance Tips

  • Bundle Size: Keep under 1MB compressed
  • Cold Starts: Minimize top-level code
  • Streaming: Use streaming SSR when available
  • Caching: Leverage Cache API and CDN
  • Code Splitting: Dynamic imports for routes

See Also

  • workers-performance - Optimization techniques
  • workers-runtime-apis - Workers APIs reference
  • cloudflare-worker-base - Basic Workers setup

How to use it

Copy the folder

Take secondsky/cloudflare-workers-frameworks from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.