**Production-tested**: cloudflare-worker-base-test (https://cloudflare-worker-base-test.webfonts.workers.dev)
/plugin marketplace add secondsky/claude-skills/plugin install cloudflare-worker-base@claude-skillsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/advanced-patterns.mdreferences/api-patterns.mdreferences/architecture.mdreferences/common-issues.mdreferences/deployment.mdtemplates/package.jsontemplates/public/index.htmltemplates/public/script.jstemplates/public/styles.csstemplates/src/index.tstemplates/tsconfig.jsontemplates/vite.config.tstemplates/wrangler.jsoncProduction-tested: cloudflare-worker-base-test (https://cloudflare-worker-base-test.webfonts.workers.dev) Last Updated: 2025-11-25 Status: Production Ready ✅
npm create cloudflare@latest my-worker -- \
--type hello-world \
--ts \
--git \
--deploy false \
--framework none
Flags: --type hello-world (clean start), --ts (TypeScript), --git (init repo), --deploy false (configure first), --framework none (add Vite manually)
cd my-worker
bun add hono@4.10.6 # preferred
# or: npm add hono@4.10.6
bun add -d @cloudflare/vite-plugin@1.15.2 vite@latest wrangler@4.50.0
# or: npm add -d @cloudflare/vite-plugin@1.15.2 vite@latest wrangler@4.50.0
Version Notes:
hono@4.10.6: Minimum recommended version (verified 2025-11-20)@cloudflare/vite-plugin@1.15.2: Minimum recommended version, includes HMR fixeswrangler@4.50.0: Latest stable version (verified 2025-11-23)vite: Latest version compatible with Cloudflare pluginCreate or update wrangler.jsonc:
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "my-worker",
"main": "src/index.ts",
"account_id": "YOUR_ACCOUNT_ID",
"compatibility_date": "2025-10-11",
"observability": {
"enabled": true
},
"assets": {
"directory": "./public/",
"binding": "ASSETS",
"not_found_handling": "single-page-application",
"run_worker_first": ["/api/*"]
}
}
CRITICAL: run_worker_first Configuration
index.html instead of JSONCreate vite.config.ts:
import { defineConfig } from 'vite'
import { cloudflare } from '@cloudflare/vite-plugin'
export default defineConfig({
plugins: [
cloudflare({
// Optional: Configure the plugin if needed
}),
],
})
Why: Official Cloudflare plugin with HMR support, local Miniflare development, v1.15.2+ fixes HMR crashes
Create src/index.ts:
/**
* Cloudflare Worker with Hono
*
* CRITICAL: Export pattern to prevent build errors
* ✅ CORRECT: export default app
* ❌ WRONG: export default { fetch: app.fetch }
*/
import { Hono } from 'hono'
// Type-safe environment bindings
type Bindings = {
ASSETS: Fetcher
}
const app = new Hono<{ Bindings: Bindings }>()
/**
* API Routes
* Handled BEFORE static assets due to run_worker_first config
*/
app.get('/api/hello', (c) => {
return c.json({
message: 'Hello from Cloudflare Workers!',
timestamp: new Date().toISOString(),
})
})
app.get('/api/health', (c) => {
return c.json({
status: 'ok',
version: '1.0.0',
environment: c.env ? 'production' : 'development',
})
})
/**
* Fallback to Static Assets
* Any route not matched above is served from public/ directory
*/
app.all('*', (c) => {
return c.env.ASSETS.fetch(c.req.raw)
})
/**
* Export the Hono app directly (ES Module format)
* This is the correct pattern for Cloudflare Workers with Hono + Vite
*/
export default app
Why This Export Pattern:
{ fetch: app.fetch } causes: "Cannot read properties of undefined (reading 'map')"export default {
fetch: app.fetch,
scheduled: async (event, env, ctx) => { /* ... */ }
}
Create public/index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Worker App</title>
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<div class="container">
<h1>Cloudflare Worker + Static Assets</h1>
<button onclick="testAPI()">Test API</button>
<pre id="output"></pre>
</div>
<script src="/script.js"></script>
</body>
</html>
Create public/script.js:
async function testAPI() {
const response = await fetch('/api/hello')
const data = await response.json()
document.getElementById('output').textContent = JSON.stringify(data, null, 2)
}
Create public/styles.css:
body {
font-family: system-ui, -apple-system, sans-serif;
max-width: 800px;
margin: 40px auto;
padding: 20px;
}
button {
background: #0070f3;
color: white;
border: none;
padding: 12px 24px;
border-radius: 6px;
cursor: pointer;
}
pre {
background: #f5f5f5;
padding: 16px;
border-radius: 6px;
overflow-x: auto;
}
Update package.json:
{
"scripts": {
"dev": "wrangler dev",
"deploy": "wrangler deploy",
"cf-typegen": "wrangler types"
}
}
# Generate TypeScript types for bindings
npm run cf-typegen
# Start local dev server (http://localhost:8787)
npm run dev
# Deploy to production
npm run deploy
This skill prevents 6 documented issues:
Error: "Cannot read properties of undefined (reading 'map')"
Source: honojs/hono #3955
Prevention: Use export default app (NOT { fetch: app.fetch })
Error: API routes return index.html instead of JSON
Source: workers-sdk #8879
Prevention: Add "run_worker_first": ["/api/*"] to wrangler.jsonc
Error: "Handler does not export a scheduled() function" Source: honojs/vite-plugins #275 Prevention: Use Module Worker format when needed:
export default {
fetch: app.fetch,
scheduled: async (event, env, ctx) => { /* ... */ }
}
Error: "A hanging Promise was canceled" during development
Source: workers-sdk #9518
Prevention: Use @cloudflare/vite-plugin@1.15.2 or later
Error: Non-deterministic deployment failures in CI/CD Source: workers-sdk #7555 Prevention: Use Wrangler 4.x+ with retry logic (fixed in recent versions)
Error: Using deprecated Service Worker format Source: Cloudflare migration guide Prevention: Always use ES Module format (shown in Step 1)
wrangler.jsonc - Worker configuration (account_id, assets, bindings for KV/D1/R2)
{
"name": "my-worker",
"main": "src/index.ts",
"account_id": "YOUR_ACCOUNT_ID",
"compatibility_date": "2025-10-11",
"observability": { "enabled": true },
"assets": {
"directory": "./public/",
"binding": "ASSETS",
"not_found_handling": "single-page-application",
"run_worker_first": ["/api/*"]
}
}
vite.config.ts - Vite + Cloudflare plugin
import { defineConfig } from 'vite'
import { cloudflare } from '@cloudflare/vite-plugin'
export default defineConfig({
plugins: [cloudflare({ persistState: true })],
server: { port: 8787 },
})
tsconfig.json - TypeScript configuration (ES2022, bundler resolution, Workers types)
{
"compilerOptions": {
"target": "ES2022",
"moduleResolution": "bundler",
"lib": ["es2022", "webworker"],
"types": ["@cloudflare/workers-types"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"isolatedModules": true
},
"include": ["src"],
"exclude": ["node_modules"]
}
Hono provides powerful routing and request handling. See references/api-patterns.md for comprehensive examples including:
/api/users/:id) and query strings (?q=search)Load references/api-patterns.md when: Implementing specific API patterns beyond basic GET/POST.
Directory: public/ contains all static files (HTML, CSS, JS, images)
SPA Fallback: "not_found_handling": "single-page-application" returns index.html for unknown routes (useful for React Router, Vue Router).
Route Priority with run_worker_first: ["/api/*"]:
/api/* → Worker handles (returns JSON)/ → Static Assets serve index.html/unknown → SPA fallback returns index.htmlCache Busting: Use query strings: <link href="/styles.css?v=1.0.0">
For complete workflow details, see references/deployment.md which covers:
npm run dev (HMR, testing, type generation)wrangler deploy, environment-specific deploys)Load references/deployment.md when: Setting up CI/CD, deploying to production, or monitoring deployed workers.
hono@4.10.6, @cloudflare/vite-plugin@1.15.2, wrangler@4.50.0)wrangler.jsonc configured (account_id, assets, run_worker_first, compatibility_date)vite.config.ts created with cloudflare pluginsrc/index.ts uses export default app (NOT { fetch: app.fetch })public/ directory with static filesnpm run cf-typegen → types generatednpm run dev → server starts without errorsnpm run deployFor advanced usage, see references/advanced-patterns.md which covers:
Load references/advanced-patterns.md when: Implementing middleware, multi-environment setups, custom error handling, or test suites.
Templates in templates/ directory: wrangler.jsonc, vite.config.ts, package.json, tsconfig.json, src/index.ts, public/index.html, public/styles.css, public/script.js
Copy to your project and customize as needed.
This skill uses progressive disclosure. Load these references when needed:
references/api-patterns.mdLoad when implementing specific API patterns:
:id) or query strings (?q=)references/advanced-patterns.mdLoad when implementing advanced features:
references/deployment.mdLoad when deploying or setting up automation:
/websites/developers_cloudflare-workers{
"dependencies": {
"hono": "^4.10.6"
},
"devDependencies": {
"@cloudflare/vite-plugin": "^1.15.2",
"@cloudflare/workers-types": "^4.20251011.0",
"vite": "^7.0.0",
"wrangler": "^4.50.0",
"typescript": "^5.9.0"
}
}
Live Example: https://cloudflare-worker-base-test.webfonts.workers.dev Build Time: ~45 minutes | Errors Prevented: 6/6 | Status: ✅ Production Ready
All patterns validated in production deployment.
Troubleshooting Quick Checks:
export default app (not { fetch: app.fetch })run_worker_first: ["/api/*"] in wrangler.jsoncCreating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.