[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7AK64NFGC41CSQ7F3A99SRE":3,"skill-same:01M7AK64NFGC41CSQ7F3A99SRE":59},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":18,"linkOnly":19,"markdownContent":20,"markdownBody":21,"frontMatter":22,"refName":24,"commitSha":25,"skillDirectory":5,"forksCount":13,"repositoryHtmlUrl":26,"repositoryHomepageUrl":6,"ownerHtmlUrl":27,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":28,"install":29,"resources":42},"01M7AK64NFGC41CSQ7F3A99SRE","cloudflare-worker-base",null,"Production-tested setup for Cloudflare Workers with Hono, Vite, and Static Assets.\n\nUse when: creating new Cloudflare Workers projects, setting up Hono routing with Workers,\nconfiguring Vite plugin for Workers, adding Static Assets to Workers, deploying with Wrangler,\nor encountering deployment errors, routing conflicts, or HMR crashes.\n\nPrevents 6 documented issues: export syntax errors, Static Assets routing conflicts,\nscheduled handler errors, HMR race conditions, upload race conditions, and Service Worker\nformat confusion.\n\nKeywords: Cloudflare Workers, CF Workers, Hono, wrangler, Vite, Static Assets, @cloudflare\u002Fvite-plugin,\nwrangler.jsonc, ES Module, run_worker_first, SPA fallback, API routes, serverless, edge computing,\n\"Cannot read properties of undefined\", \"Static Assets 404\", \"A hanging Promise was canceled\",\n\"Handler does not export\", deployment fails, routing not working, HMR crashes","davidanthonyn\u002Fclaude-skills","davidanthonyn","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F55152980?v=4","01M7AJ4MY8S5C2RJCGX6626J0G","01M7AJ7JE1K98GRPH9Z57Z0R0W",0,"MIT","https:\u002F\u002Fgithub.com\u002Fdavidanthonyn\u002Fclaude-skills\u002Fblob\u002Fmain\u002Fcloudflare-worker-base\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: cloudflare-worker-base\ndescription: |\n  Production-tested setup for Cloudflare Workers with Hono, Vite, and Static Assets.\n\n  Use when: creating new Cloudflare Workers projects, setting up Hono routing with Workers,\n  configuring Vite plugin for Workers, adding Static Assets to Workers, deploying with Wrangler,\n  or encountering deployment errors, routing conflicts, or HMR crashes.\n\n  Prevents 6 documented issues: export syntax errors, Static Assets routing conflicts,\n  scheduled handler errors, HMR race conditions, upload race conditions, and Service Worker\n  format confusion.\n\n  Keywords: Cloudflare Workers, CF Workers, Hono, wrangler, Vite, Static Assets, @cloudflare\u002Fvite-plugin,\n  wrangler.jsonc, ES Module, run_worker_first, SPA fallback, API routes, serverless, edge computing,\n  \"Cannot read properties of undefined\", \"Static Assets 404\", \"A hanging Promise was canceled\",\n  \"Handler does not export\", deployment fails, routing not working, HMR crashes\nlicense: MIT\n---\n\n# Cloudflare Worker Base Stack\n\n**Production-tested**: cloudflare-worker-base-test (https:\u002F\u002Fcloudflare-worker-base-test.webfonts.workers.dev)\n**Last Updated**: 2025-10-20\n**Status**: Production Ready ✅\n\n---\n\n## Quick Start (5 Minutes)\n\n### 1. Scaffold Project\n\n```bash\nnpm create cloudflare@latest my-worker -- \\\n  --type hello-world \\\n  --ts \\\n  --git \\\n  --deploy false \\\n  --framework none\n```\n\n**Why these flags:**\n- `--type hello-world`: Clean starting point\n- `--ts`: TypeScript support\n- `--git`: Initialize git repo\n- `--deploy false`: Don't deploy yet (configure first)\n- `--framework none`: We'll add Vite ourselves\n\n### 2. Install Dependencies\n\n```bash\ncd my-worker\nnpm install hono@4.10.1\nnpm install -D @cloudflare\u002Fvite-plugin@1.13.13 vite@latest\n```\n\n**Version Notes:**\n- `hono@4.10.1`: Latest stable (verified 2025-10-20)\n- `@cloudflare\u002Fvite-plugin@1.13.13`: Latest stable, fixes HMR race condition\n- `vite`: Latest version compatible with Cloudflare plugin\n\n### 3. Configure Wrangler\n\nCreate or update `wrangler.jsonc`:\n\n```jsonc\n{\n  \"$schema\": \"node_modules\u002Fwrangler\u002Fconfig-schema.json\",\n  \"name\": \"my-worker\",\n  \"main\": \"src\u002Findex.ts\",\n  \"account_id\": \"YOUR_ACCOUNT_ID\",\n  \"compatibility_date\": \"2025-10-11\",\n  \"observability\": {\n    \"enabled\": true\n  },\n  \"assets\": {\n    \"directory\": \".\u002Fpublic\u002F\",\n    \"binding\": \"ASSETS\",\n    \"not_found_handling\": \"single-page-application\",\n    \"run_worker_first\": [\"\u002Fapi\u002F*\"]\n  }\n}\n```\n\n**CRITICAL: `run_worker_first` Configuration**\n- Without this, SPA fallback intercepts API routes\n- API routes return `index.html` instead of JSON\n- Source: [workers-sdk #8879](https:\u002F\u002Fgithub.com\u002Fcloudflare\u002Fworkers-sdk\u002Fissues\u002F8879)\n\n### 4. Configure Vite\n\nCreate `vite.config.ts`:\n\n```typescript\nimport { defineConfig } from 'vite'\nimport { cloudflare } from '@cloudflare\u002Fvite-plugin'\n\nexport default defineConfig({\n  plugins: [\n    cloudflare({\n      \u002F\u002F Optional: Configure the plugin if needed\n    }),\n  ],\n})\n```\n\n**Why @cloudflare\u002Fvite-plugin:**\n- Official plugin from Cloudflare\n- Supports HMR with Workers\n- Enables local development with Miniflare\n- Version 1.13.13 fixes \"A hanging Promise was canceled\" error\n\n---\n\n## The Four-Step Setup Process\n\n### Step 1: Create Hono App with API Routes\n\nCreate `src\u002Findex.ts`:\n\n```typescript\n\u002F**\n * Cloudflare Worker with Hono\n *\n * CRITICAL: Export pattern to prevent build errors\n * ✅ CORRECT: export default app\n * ❌ WRONG:   export default { fetch: app.fetch }\n *\u002F\n\nimport { Hono } from 'hono'\n\n\u002F\u002F Type-safe environment bindings\ntype Bindings = {\n  ASSETS: Fetcher\n}\n\nconst app = new Hono\u003C{ Bindings: Bindings }>()\n\n\u002F**\n * API Routes\n * Handled BEFORE static assets due to run_worker_first config\n *\u002F\napp.get('\u002Fapi\u002Fhello', (c) => {\n  return c.json({\n    message: 'Hello from Cloudflare Workers!',\n    timestamp: new Date().toISOString(),\n  })\n})\n\napp.get('\u002Fapi\u002Fhealth', (c) => {\n  return c.json({\n    status: 'ok',\n    version: '1.0.0',\n    environment: c.env ? 'production' : 'development',\n  })\n})\n\n\u002F**\n * Fallback to Static Assets\n * Any route not matched above is served from public\u002F directory\n *\u002F\napp.all('*', (c) => {\n  return c.env.ASSETS.fetch(c.req.raw)\n})\n\n\u002F**\n * Export the Hono app directly (ES Module format)\n * This is the correct pattern for Cloudflare Workers with Hono + Vite\n *\u002F\nexport default app\n```\n\n**Why This Export Pattern:**\n- Source: [honojs\u002Fhono #3955](https:\u002F\u002Fgithub.com\u002Fhonojs\u002Fhono\u002Fissues\u002F3955)\n- Using `{ fetch: app.fetch }` causes: \"Cannot read properties of undefined (reading 'map')\"\n- Exception: If you need scheduled\u002Ftail handlers, use Module Worker format:\n  ```typescript\n  export default {\n    fetch: app.fetch,\n    scheduled: async (event, env, ctx) => { \u002F* ... *\u002F }\n  }\n  ```\n\n### Step 2: Create Static Frontend\n\nCreate `public\u002Findex.html`:\n\n```html\n\u003C!DOCTYPE html>\n\u003Chtml lang=\"en\">\n\u003Chead>\n  \u003Cmeta charset=\"UTF-8\">\n  \u003Cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \u003Ctitle>My Worker App\u003C\u002Ftitle>\n  \u003Clink rel=\"stylesheet\" href=\"\u002Fstyles.css\">\n\u003C\u002Fhead>\n\u003Cbody>\n  \u003Cdiv class=\"container\">\n    \u003Ch1>Cloudflare Worker + Static Assets\u003C\u002Fh1>\n    \u003Cbutton onclick=\"testAPI()\">Test API\u003C\u002Fbutton>\n    \u003Cpre id=\"output\">\u003C\u002Fpre>\n  \u003C\u002Fdiv>\n  \u003Cscript src=\"\u002Fscript.js\">\u003C\u002Fscript>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>\n```\n\nCreate `public\u002Fscript.js`:\n\n```javascript\nasync function testAPI() {\n  const response = await fetch('\u002Fapi\u002Fhello')\n  const data = await response.json()\n  document.getElementById('output').textContent = JSON.stringify(data, null, 2)\n}\n```\n\nCreate `public\u002Fstyles.css`:\n\n```css\nbody {\n  font-family: system-ui, -apple-system, sans-serif;\n  max-width: 800px;\n  margin: 40px auto;\n  padding: 20px;\n}\n\nbutton {\n  background: #0070f3;\n  color: white;\n  border: none;\n  padding: 12px 24px;\n  border-radius: 6px;\n  cursor: pointer;\n}\n\npre {\n  background: #f5f5f5;\n  padding: 16px;\n  border-radius: 6px;\n  overflow-x: auto;\n}\n```\n\n### Step 3: Update Package Scripts\n\nUpdate `package.json`:\n\n```json\n{\n  \"scripts\": {\n    \"dev\": \"wrangler dev\",\n    \"deploy\": \"wrangler deploy\",\n    \"cf-typegen\": \"wrangler types\"\n  }\n}\n```\n\n### Step 4: Test & Deploy\n\n```bash\n# Generate TypeScript types for bindings\nnpm run cf-typegen\n\n# Start local dev server (http:\u002F\u002Flocalhost:8787)\nnpm run dev\n\n# Deploy to production\nnpm run deploy\n```\n\n---\n\n## Known Issues Prevention\n\nThis skill prevents **6 documented issues**:\n\n### Issue #1: Export Syntax Error\n**Error**: \"Cannot read properties of undefined (reading 'map')\"\n**Source**: [honojs\u002Fhono #3955](https:\u002F\u002Fgithub.com\u002Fhonojs\u002Fhono\u002Fissues\u002F3955)\n**Prevention**: Use `export default app` (NOT `{ fetch: app.fetch }`)\n\n### Issue #2: Static Assets Routing Conflicts\n**Error**: API routes return `index.html` instead of JSON\n**Source**: [workers-sdk #8879](https:\u002F\u002Fgithub.com\u002Fcloudflare\u002Fworkers-sdk\u002Fissues\u002F8879)\n**Prevention**: Add `\"run_worker_first\": [\"\u002Fapi\u002F*\"]` to wrangler.jsonc\n\n### Issue #3: Scheduled\u002FCron Not Exported\n**Error**: \"Handler does not export a scheduled() function\"\n**Source**: [honojs\u002Fvite-plugins #275](https:\u002F\u002Fgithub.com\u002Fhonojs\u002Fvite-plugins\u002Fissues\u002F275)\n**Prevention**: Use Module Worker format when needed:\n```typescript\nexport default {\n  fetch: app.fetch,\n  scheduled: async (event, env, ctx) => { \u002F* ... *\u002F }\n}\n```\n\n### Issue #4: HMR Race Condition\n**Error**: \"A hanging Promise was canceled\" during development\n**Source**: [workers-sdk #9518](https:\u002F\u002Fgithub.com\u002Fcloudflare\u002Fworkers-sdk\u002Fissues\u002F9518)\n**Prevention**: Use `@cloudflare\u002Fvite-plugin@1.13.13` or later\n\n### Issue #5: Static Assets Upload Race\n**Error**: Non-deterministic deployment failures in CI\u002FCD\n**Source**: [workers-sdk #7555](https:\u002F\u002Fgithub.com\u002Fcloudflare\u002Fworkers-sdk\u002Fissues\u002F7555)\n**Prevention**: Use Wrangler 4.x+ with retry logic (fixed in recent versions)\n\n### Issue #6: Service Worker Format Confusion\n**Error**: Using deprecated Service Worker format\n**Source**: Cloudflare migration guide\n**Prevention**: Always use ES Module format (shown in Step 1)\n\n---\n\n## Configuration Files Reference\n\n### wrangler.jsonc (Full Example)\n\n```jsonc\n{\n  \"$schema\": \"node_modules\u002Fwrangler\u002Fconfig-schema.json\",\n  \"name\": \"my-worker\",\n  \"main\": \"src\u002Findex.ts\",\n  \"account_id\": \"YOUR_ACCOUNT_ID\",\n  \"compatibility_date\": \"2025-10-11\",\n  \"observability\": {\n    \"enabled\": true\n  },\n  \"assets\": {\n    \"directory\": \".\u002Fpublic\u002F\",\n    \"binding\": \"ASSETS\",\n    \"not_found_handling\": \"single-page-application\",\n    \"run_worker_first\": [\"\u002Fapi\u002F*\"]\n  }\n  \u002F* Optional: Environment Variables *\u002F\n  \u002F\u002F \"vars\": { \"MY_VARIABLE\": \"production_value\" }\n\n  \u002F* Optional: KV Namespace Bindings *\u002F\n  \u002F\u002F \"kv_namespaces\": [\n  \u002F\u002F   { \"binding\": \"MY_KV\", \"id\": \"YOUR_KV_ID\" }\n  \u002F\u002F ]\n\n  \u002F* Optional: D1 Database Bindings *\u002F\n  \u002F\u002F \"d1_databases\": [\n  \u002F\u002F   { \"binding\": \"DB\", \"database_name\": \"my-db\", \"database_id\": \"YOUR_DB_ID\" }\n  \u002F\u002F ]\n\n  \u002F* Optional: R2 Bucket Bindings *\u002F\n  \u002F\u002F \"r2_buckets\": [\n  \u002F\u002F   { \"binding\": \"MY_BUCKET\", \"bucket_name\": \"my-bucket\" }\n  \u002F\u002F ]\n}\n```\n\n**Why wrangler.jsonc over wrangler.toml:**\n- JSON format preferred since Wrangler v3.91.0\n- Better IDE support with JSON schema\n- Comments allowed with JSONC\n\n### vite.config.ts (Full Example)\n\n```typescript\nimport { defineConfig } from 'vite'\nimport { cloudflare } from '@cloudflare\u002Fvite-plugin'\n\nexport default defineConfig({\n  plugins: [\n    cloudflare({\n      \u002F\u002F Persist state between HMR updates\n      persist: true,\n    }),\n  ],\n\n  \u002F\u002F Optional: Configure server\n  server: {\n    port: 8787,\n  },\n\n  \u002F\u002F Optional: Build optimizations\n  build: {\n    target: 'esnext',\n    minify: true,\n  },\n})\n```\n\n### tsconfig.json\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ES2022\",\n    \"lib\": [\"ES2022\"],\n    \"moduleResolution\": \"bundler\",\n    \"types\": [\"@cloudflare\u002Fworkers-types\u002F2023-07-01\"],\n    \"resolveJsonModule\": true,\n    \"allowJs\": true,\n    \"checkJs\": false,\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"isolatedModules\": true,\n    \"noEmit\": true\n  },\n  \"include\": [\"src\u002F**\u002F*\"],\n  \"exclude\": [\"node_modules\"]\n}\n```\n\n---\n\n## API Route Patterns\n\n### Basic JSON Response\n\n```typescript\napp.get('\u002Fapi\u002Fusers', (c) => {\n  return c.json({\n    users: [\n      { id: 1, name: 'Alice' },\n      { id: 2, name: 'Bob' }\n    ]\n  })\n})\n```\n\n### POST with Request Body\n\n```typescript\napp.post('\u002Fapi\u002Fusers', async (c) => {\n  const body = await c.req.json()\n\n  \u002F\u002F Validate and process body\n  return c.json({ success: true, data: body }, 201)\n})\n```\n\n### Route Parameters\n\n```typescript\napp.get('\u002Fapi\u002Fusers\u002F:id', (c) => {\n  const id = c.req.param('id')\n  return c.json({ id, name: 'User' })\n})\n```\n\n### Query Parameters\n\n```typescript\napp.get('\u002Fapi\u002Fsearch', (c) => {\n  const query = c.req.query('q')\n  return c.json({ query, results: [] })\n})\n```\n\n### Error Handling\n\n```typescript\napp.get('\u002Fapi\u002Fdata', async (c) => {\n  try {\n    \u002F\u002F Your logic here\n    return c.json({ success: true })\n  } catch (error) {\n    return c.json({ error: error.message }, 500)\n  }\n})\n```\n\n### Using Bindings (KV, D1, R2)\n\n```typescript\ntype Bindings = {\n  ASSETS: Fetcher\n  MY_KV: KVNamespace\n  DB: D1Database\n  MY_BUCKET: R2Bucket\n}\n\nconst app = new Hono\u003C{ Bindings: Bindings }>()\n\napp.get('\u002Fapi\u002Fdata', async (c) => {\n  \u002F\u002F KV\n  const value = await c.env.MY_KV.get('key')\n\n  \u002F\u002F D1\n  const result = await c.env.DB.prepare('SELECT * FROM users').all()\n\n  \u002F\u002F R2\n  const object = await c.env.MY_BUCKET.get('file.txt')\n\n  return c.json({ value, result, object })\n})\n```\n\n---\n\n## Static Assets Best Practices\n\n### Directory Structure\n\n```\npublic\u002F\n├── index.html          # Main entry point\n├── styles.css          # Global styles\n├── script.js           # Client-side JavaScript\n├── favicon.ico         # Favicon\n└── assets\u002F             # Images, fonts, etc.\n    ├── logo.png\n    └── fonts\u002F\n```\n\n### SPA Fallback\n\nThe `\"not_found_handling\": \"single-page-application\"` configuration means:\n- Unknown routes return `index.html`\n- Useful for React Router, Vue Router, etc.\n- BUT requires `run_worker_first` for API routes!\n\n### Route Priority\n\nWith `\"run_worker_first\": [\"\u002Fapi\u002F*\"]`:\n\n1. `\u002Fapi\u002Fhello` → Worker handles it (returns JSON)\n2. `\u002F` → Static Assets serve `index.html`\n3. `\u002Fstyles.css` → Static Assets serve `styles.css`\n4. `\u002Funknown` → Static Assets serve `index.html` (SPA fallback)\n\n### Caching Static Assets\n\nStatic Assets are automatically cached at the edge. To bust cache:\n```html\n\u003Clink rel=\"stylesheet\" href=\"\u002Fstyles.css?v=1.0.0\">\n\u003Cscript src=\"\u002Fscript.js?v=1.0.0\">\u003C\u002Fscript>\n```\n\n---\n\n## Development Workflow\n\n### Local Development\n\n```bash\nnpm run dev\n```\n\n- Server runs on http:\u002F\u002Flocalhost:8787\n- HMR enabled (file changes reload automatically)\n- Uses Miniflare for local simulation\n- All bindings work locally (KV, D1, R2)\n\n### Testing API Routes\n\n```bash\n# Test GET endpoint\ncurl http:\u002F\u002Flocalhost:8787\u002Fapi\u002Fhello\n\n# Test POST endpoint\ncurl -X POST http:\u002F\u002Flocalhost:8787\u002Fapi\u002Fecho \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"test\": \"data\"}'\n```\n\n### Type Generation\n\n```bash\nnpm run cf-typegen\n```\n\nGenerates `worker-configuration.d.ts` with:\n- Binding types (KV, D1, R2, etc.)\n- Environment variable types\n- Auto-completes in your editor\n\n### Deployment\n\n```bash\n# Deploy to production\nnpm run deploy\n\n# Deploy to specific environment\nwrangler deploy --env staging\n\n# Tail logs in production\nwrangler tail\n\n# Check deployment status\nwrangler deployments list\n```\n\n---\n\n## Complete Setup Checklist\n\n- [ ] Project scaffolded with `npm create cloudflare@latest`\n- [ ] Dependencies installed: `hono@4.10.1`, `@cloudflare\u002Fvite-plugin@1.13.13`\n- [ ] `wrangler.jsonc` created with:\n  - [ ] `account_id` set to your Cloudflare account\n  - [ ] `assets.directory` pointing to `.\u002Fpublic\u002F`\n  - [ ] `assets.run_worker_first` includes `\u002Fapi\u002F*`\n  - [ ] `compatibility_date` set to recent date\n- [ ] `vite.config.ts` created with `@cloudflare\u002Fvite-plugin`\n- [ ] `src\u002Findex.ts` created with Hono app\n  - [ ] Uses `export default app` (NOT `{ fetch: app.fetch }`)\n  - [ ] Includes ASSETS binding type\n  - [ ] Has fallback route: `app.all('*', (c) => c.env.ASSETS.fetch(c.req.raw))`\n- [ ] `public\u002F` directory created with static files\n- [ ] `npm run cf-typegen` executed successfully\n- [ ] `npm run dev` starts without errors\n- [ ] API routes tested in browser\u002Fcurl\n- [ ] Static assets serve correctly\n- [ ] HMR works without crashes\n- [ ] Ready to deploy with `npm run deploy`\n\n---\n\n## Advanced Topics\n\n### Adding Middleware\n\n```typescript\nimport { Hono } from 'hono'\nimport { logger } from 'hono\u002Flogger'\nimport { cors } from 'hono\u002Fcors'\n\nconst app = new Hono\u003C{ Bindings: Bindings }>()\n\n\u002F\u002F Global middleware\napp.use('*', logger())\napp.use('\u002Fapi\u002F*', cors())\n\n\u002F\u002F Route-specific middleware\napp.use('\u002Fadmin\u002F*', async (c, next) => {\n  \u002F\u002F Auth check\n  await next()\n})\n```\n\n### Environment-Specific Configuration\n\n```jsonc\n\u002F\u002F wrangler.jsonc\n{\n  \"name\": \"my-worker\",\n  \"env\": {\n    \"staging\": {\n      \"vars\": { \"ENV\": \"staging\" }\n    },\n    \"production\": {\n      \"vars\": { \"ENV\": \"production\" }\n    }\n  }\n}\n```\n\nDeploy: `wrangler deploy --env staging`\n\n### Custom Error Pages\n\n```typescript\napp.onError((err, c) => {\n  console.error(err)\n  return c.json({ error: 'Internal Server Error' }, 500)\n})\n\napp.notFound((c) => {\n  return c.json({ error: 'Not Found' }, 404)\n})\n```\n\n### Testing with Vitest\n\n```bash\nnpm install -D vitest @cloudflare\u002Fvitest-pool-workers\n```\n\nCreate `vitest.config.ts`:\n\n```typescript\nimport { defineConfig } from 'vitest\u002Fconfig'\n\nexport default defineConfig({\n  test: {\n    poolOptions: {\n      workers: {\n        wrangler: { configPath: '.\u002Fwrangler.jsonc' },\n      },\n    },\n  },\n})\n```\n\nSee `reference\u002Ftesting.md` for complete testing guide.\n\n---\n\n## File Templates\n\nAll templates are available in the `templates\u002F` directory:\n\n- **wrangler.jsonc** - Complete Worker configuration\n- **vite.config.ts** - Vite + Cloudflare plugin setup\n- **package.json** - Dependencies and scripts\n- **tsconfig.json** - TypeScript configuration\n- **src\u002Findex.ts** - Hono app with API routes\n- **public\u002Findex.html** - Static frontend example\n- **public\u002Fstyles.css** - Example styling\n- **public\u002Fscript.js** - API test functions\n\nCopy these files to your project and customize as needed.\n\n---\n\n## Reference Documentation\n\nFor deeper understanding, see:\n\n- **architecture.md** - Deep dive into export patterns, routing, and Static Assets\n- **common-issues.md** - All 6 issues with detailed troubleshooting\n- **deployment.md** - Wrangler commands, CI\u002FCD patterns, and production tips\n\n---\n\n## Official Documentation\n\n- **Cloudflare Workers**: https:\u002F\u002Fdevelopers.cloudflare.com\u002Fworkers\u002F\n- **Static Assets**: https:\u002F\u002Fdevelopers.cloudflare.com\u002Fworkers\u002Fstatic-assets\u002F\n- **Vite Plugin**: https:\u002F\u002Fdevelopers.cloudflare.com\u002Fworkers\u002Fvite-plugin\u002F\n- **Wrangler Configuration**: https:\u002F\u002Fdevelopers.cloudflare.com\u002Fworkers\u002Fwrangler\u002Fconfiguration\u002F\n- **Hono**: https:\u002F\u002Fhono.dev\u002Fdocs\u002Fgetting-started\u002Fcloudflare-workers\n- **Context7 Library ID**: `\u002Fwebsites\u002Fdevelopers_cloudflare-workers`\n\n---\n\n## Dependencies (Latest Verified 2025-10-20)\n\n```json\n{\n  \"dependencies\": {\n    \"hono\": \"^4.10.1\"\n  },\n  \"devDependencies\": {\n    \"@cloudflare\u002Fvite-plugin\": \"^1.13.13\",\n    \"@cloudflare\u002Fworkers-types\": \"^4.20251011.0\",\n    \"vite\": \"^7.0.0\",\n    \"wrangler\": \"^4.43.0\",\n    \"typescript\": \"^5.9.0\"\n  }\n}\n```\n\n---\n\n## Production Example\n\nThis skill is based on the cloudflare-worker-base-test project:\n- **Live**: https:\u002F\u002Fcloudflare-worker-base-test.webfonts.workers.dev\n- **Build Time**: ~45 minutes (actual)\n- **Errors**: 0 (all 6 known issues prevented)\n- **Validation**: ✅ Local dev, HMR, production deployment all successful\n\nAll patterns in this skill have been validated in production.\n\n---\n\n**Questions? Issues?**\n\n1. Check `reference\u002Fcommon-issues.md` first\n2. Verify all steps in the 4-step setup process\n3. Ensure `export default app` (not `{ fetch: app.fetch }`)\n4. Ensure `run_worker_first` is configured\n5. Check official docs: https:\u002F\u002Fdevelopers.cloudflare.com\u002Fworkers\u002F\n","# Cloudflare Worker Base Stack\n\n**Production-tested**: cloudflare-worker-base-test (https:\u002F\u002Fcloudflare-worker-base-test.webfonts.workers.dev)\n**Last Updated**: 2025-10-20\n**Status**: Production Ready ✅\n\n---\n\n## Quick Start (5 Minutes)\n\n### 1. Scaffold Project\n\n```bash\nnpm create cloudflare@latest my-worker -- \\\n  --type hello-world \\\n  --ts \\\n  --git \\\n  --deploy false \\\n  --framework none\n```\n\n**Why these flags:**\n- `--type hello-world`: Clean starting point\n- `--ts`: TypeScript support\n- `--git`: Initialize git repo\n- `--deploy false`: Don't deploy yet (configure first)\n- `--framework none`: We'll add Vite ourselves\n\n### 2. Install Dependencies\n\n```bash\ncd my-worker\nnpm install hono@4.10.1\nnpm install -D @cloudflare\u002Fvite-plugin@1.13.13 vite@latest\n```\n\n**Version Notes:**\n- `hono@4.10.1`: Latest stable (verified 2025-10-20)\n- `@cloudflare\u002Fvite-plugin@1.13.13`: Latest stable, fixes HMR race condition\n- `vite`: Latest version compatible with Cloudflare plugin\n\n### 3. Configure Wrangler\n\nCreate or update `wrangler.jsonc`:\n\n```jsonc\n{\n  \"$schema\": \"node_modules\u002Fwrangler\u002Fconfig-schema.json\",\n  \"name\": \"my-worker\",\n  \"main\": \"src\u002Findex.ts\",\n  \"account_id\": \"YOUR_ACCOUNT_ID\",\n  \"compatibility_date\": \"2025-10-11\",\n  \"observability\": {\n    \"enabled\": true\n  },\n  \"assets\": {\n    \"directory\": \".\u002Fpublic\u002F\",\n    \"binding\": \"ASSETS\",\n    \"not_found_handling\": \"single-page-application\",\n    \"run_worker_first\": [\"\u002Fapi\u002F*\"]\n  }\n}\n```\n\n**CRITICAL: `run_worker_first` Configuration**\n- Without this, SPA fallback intercepts API routes\n- API routes return `index.html` instead of JSON\n- Source: [workers-sdk #8879](https:\u002F\u002Fgithub.com\u002Fcloudflare\u002Fworkers-sdk\u002Fissues\u002F8879)\n\n### 4. Configure Vite\n\nCreate `vite.config.ts`:\n\n```typescript\nimport { defineConfig } from 'vite'\nimport { cloudflare } from '@cloudflare\u002Fvite-plugin'\n\nexport default defineConfig({\n  plugins: [\n    cloudflare({\n      \u002F\u002F Optional: Configure the plugin if needed\n    }),\n  ],\n})\n```\n\n**Why @cloudflare\u002Fvite-plugin:**\n- Official plugin from Cloudflare\n- Supports HMR with Workers\n- Enables local development with Miniflare\n- Version 1.13.13 fixes \"A hanging Promise was canceled\" error\n\n---\n\n## The Four-Step Setup Process\n\n### Step 1: Create Hono App with API Routes\n\nCreate `src\u002Findex.ts`:\n\n```typescript\n\u002F**\n * Cloudflare Worker with Hono\n *\n * CRITICAL: Export pattern to prevent build errors\n * ✅ CORRECT: export default app\n * ❌ WRONG:   export default { fetch: app.fetch }\n *\u002F\n\nimport { Hono } from 'hono'\n\n\u002F\u002F Type-safe environment bindings\ntype Bindings = {\n  ASSETS: Fetcher\n}\n\nconst app = new Hono\u003C{ Bindings: Bindings }>()\n\n\u002F**\n * API Routes\n * Handled BEFORE static assets due to run_worker_first config\n *\u002F\napp.get('\u002Fapi\u002Fhello', (c) => {\n  return c.json({\n    message: 'Hello from Cloudflare Workers!',\n    timestamp: new Date().toISOString(),\n  })\n})\n\napp.get('\u002Fapi\u002Fhealth', (c) => {\n  return c.json({\n    status: 'ok',\n    version: '1.0.0',\n    environment: c.env ? 'production' : 'development',\n  })\n})\n\n\u002F**\n * Fallback to Static Assets\n * Any route not matched above is served from public\u002F directory\n *\u002F\napp.all('*', (c) => {\n  return c.env.ASSETS.fetch(c.req.raw)\n})\n\n\u002F**\n * Export the Hono app directly (ES Module format)\n * This is the correct pattern for Cloudflare Workers with Hono + Vite\n *\u002F\nexport default app\n```\n\n**Why This Export Pattern:**\n- Source: [honojs\u002Fhono #3955](https:\u002F\u002Fgithub.com\u002Fhonojs\u002Fhono\u002Fissues\u002F3955)\n- Using `{ fetch: app.fetch }` causes: \"Cannot read properties of undefined (reading 'map')\"\n- Exception: If you need scheduled\u002Ftail handlers, use Module Worker format:\n  ```typescript\n  export default {\n    fetch: app.fetch,\n    scheduled: async (event, env, ctx) => { \u002F* ... *\u002F }\n  }\n  ```\n\n### Step 2: Create Static Frontend\n\nCreate `public\u002Findex.html`:\n\n```html\n\u003C!DOCTYPE html>\n\u003Chtml lang=\"en\">\n\u003Chead>\n  \u003Cmeta charset=\"UTF-8\">\n  \u003Cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \u003Ctitle>My Worker App\u003C\u002Ftitle>\n  \u003Clink rel=\"stylesheet\" href=\"\u002Fstyles.css\">\n\u003C\u002Fhead>\n\u003Cbody>\n  \u003Cdiv class=\"container\">\n    \u003Ch1>Cloudflare Worker + Static Assets\u003C\u002Fh1>\n    \u003Cbutton onclick=\"testAPI()\">Test API\u003C\u002Fbutton>\n    \u003Cpre id=\"output\">\u003C\u002Fpre>\n  \u003C\u002Fdiv>\n  \u003Cscript src=\"\u002Fscript.js\">\u003C\u002Fscript>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>\n```\n\nCreate `public\u002Fscript.js`:\n\n```javascript\nasync function testAPI() {\n  const response = await fetch('\u002Fapi\u002Fhello')\n  const data = await response.json()\n  document.getElementById('output').textContent = JSON.stringify(data, null, 2)\n}\n```\n\nCreate `public\u002Fstyles.css`:\n\n```css\nbody {\n  font-family: system-ui, -apple-system, sans-serif;\n  max-width: 800px;\n  margin: 40px auto;\n  padding: 20px;\n}\n\nbutton {\n  background: #0070f3;\n  color: white;\n  border: none;\n  padding: 12px 24px;\n  border-radius: 6px;\n  cursor: pointer;\n}\n\npre {\n  background: #f5f5f5;\n  padding: 16px;\n  border-radius: 6px;\n  overflow-x: auto;\n}\n```\n\n### Step 3: Update Package Scripts\n\nUpdate `package.json`:\n\n```json\n{\n  \"scripts\": {\n    \"dev\": \"wrangler dev\",\n    \"deploy\": \"wrangler deploy\",\n    \"cf-typegen\": \"wrangler types\"\n  }\n}\n```\n\n### Step 4: Test & Deploy\n\n```bash\n# Generate TypeScript types for bindings\nnpm run cf-typegen\n\n# Start local dev server (http:\u002F\u002Flocalhost:8787)\nnpm run dev\n\n# Deploy to production\nnpm run deploy\n```\n\n---\n\n## Known Issues Prevention\n\nThis skill prevents **6 documented issues**:\n\n### Issue #1: Export Syntax Error\n**Error**: \"Cannot read properties of undefined (reading 'map')\"\n**Source**: [honojs\u002Fhono #3955](https:\u002F\u002Fgithub.com\u002Fhonojs\u002Fhono\u002Fissues\u002F3955)\n**Prevention**: Use `export default app` (NOT `{ fetch: app.fetch }`)\n\n### Issue #2: Static Assets Routing Conflicts\n**Error**: API routes return `index.html` instead of JSON\n**Source**: [workers-sdk #8879](https:\u002F\u002Fgithub.com\u002Fcloudflare\u002Fworkers-sdk\u002Fissues\u002F8879)\n**Prevention**: Add `\"run_worker_first\": [\"\u002Fapi\u002F*\"]` to wrangler.jsonc\n\n### Issue #3: Scheduled\u002FCron Not Exported\n**Error**: \"Handler does not export a scheduled() function\"\n**Source**: [honojs\u002Fvite-plugins #275](https:\u002F\u002Fgithub.com\u002Fhonojs\u002Fvite-plugins\u002Fissues\u002F275)\n**Prevention**: Use Module Worker format when needed:\n```typescript\nexport default {\n  fetch: app.fetch,\n  scheduled: async (event, env, ctx) => { \u002F* ... *\u002F }\n}\n```\n\n### Issue #4: HMR Race Condition\n**Error**: \"A hanging Promise was canceled\" during development\n**Source**: [workers-sdk #9518](https:\u002F\u002Fgithub.com\u002Fcloudflare\u002Fworkers-sdk\u002Fissues\u002F9518)\n**Prevention**: Use `@cloudflare\u002Fvite-plugin@1.13.13` or later\n\n### Issue #5: Static Assets Upload Race\n**Error**: Non-deterministic deployment failures in CI\u002FCD\n**Source**: [workers-sdk #7555](https:\u002F\u002Fgithub.com\u002Fcloudflare\u002Fworkers-sdk\u002Fissues\u002F7555)\n**Prevention**: Use Wrangler 4.x+ with retry logic (fixed in recent versions)\n\n### Issue #6: Service Worker Format Confusion\n**Error**: Using deprecated Service Worker format\n**Source**: Cloudflare migration guide\n**Prevention**: Always use ES Module format (shown in Step 1)\n\n---\n\n## Configuration Files Reference\n\n### wrangler.jsonc (Full Example)\n\n```jsonc\n{\n  \"$schema\": \"node_modules\u002Fwrangler\u002Fconfig-schema.json\",\n  \"name\": \"my-worker\",\n  \"main\": \"src\u002Findex.ts\",\n  \"account_id\": \"YOUR_ACCOUNT_ID\",\n  \"compatibility_date\": \"2025-10-11\",\n  \"observability\": {\n    \"enabled\": true\n  },\n  \"assets\": {\n    \"directory\": \".\u002Fpublic\u002F\",\n    \"binding\": \"ASSETS\",\n    \"not_found_handling\": \"single-page-application\",\n    \"run_worker_first\": [\"\u002Fapi\u002F*\"]\n  }\n  \u002F* Optional: Environment Variables *\u002F\n  \u002F\u002F \"vars\": { \"MY_VARIABLE\": \"production_value\" }\n\n  \u002F* Optional: KV Namespace Bindings *\u002F\n  \u002F\u002F \"kv_namespaces\": [\n  \u002F\u002F   { \"binding\": \"MY_KV\", \"id\": \"YOUR_KV_ID\" }\n  \u002F\u002F ]\n\n  \u002F* Optional: D1 Database Bindings *\u002F\n  \u002F\u002F \"d1_databases\": [\n  \u002F\u002F   { \"binding\": \"DB\", \"database_name\": \"my-db\", \"database_id\": \"YOUR_DB_ID\" }\n  \u002F\u002F ]\n\n  \u002F* Optional: R2 Bucket Bindings *\u002F\n  \u002F\u002F \"r2_buckets\": [\n  \u002F\u002F   { \"binding\": \"MY_BUCKET\", \"bucket_name\": \"my-bucket\" }\n  \u002F\u002F ]\n}\n```\n\n**Why wrangler.jsonc over wrangler.toml:**\n- JSON format preferred since Wrangler v3.91.0\n- Better IDE support with JSON schema\n- Comments allowed with JSONC\n\n### vite.config.ts (Full Example)\n\n```typescript\nimport { defineConfig } from 'vite'\nimport { cloudflare } from '@cloudflare\u002Fvite-plugin'\n\nexport default defineConfig({\n  plugins: [\n    cloudflare({\n      \u002F\u002F Persist state between HMR updates\n      persist: true,\n    }),\n  ],\n\n  \u002F\u002F Optional: Configure server\n  server: {\n    port: 8787,\n  },\n\n  \u002F\u002F Optional: Build optimizations\n  build: {\n    target: 'esnext',\n    minify: true,\n  },\n})\n```\n\n### tsconfig.json\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ES2022\",\n    \"lib\": [\"ES2022\"],\n    \"moduleResolution\": \"bundler\",\n    \"types\": [\"@cloudflare\u002Fworkers-types\u002F2023-07-01\"],\n    \"resolveJsonModule\": true,\n    \"allowJs\": true,\n    \"checkJs\": false,\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"isolatedModules\": true,\n    \"noEmit\": true\n  },\n  \"include\": [\"src\u002F**\u002F*\"],\n  \"exclude\": [\"node_modules\"]\n}\n```\n\n---\n\n## API Route Patterns\n\n### Basic JSON Response\n\n```typescript\napp.get('\u002Fapi\u002Fusers', (c) => {\n  return c.json({\n    users: [\n      { id: 1, name: 'Alice' },\n      { id: 2, name: 'Bob' }\n    ]\n  })\n})\n```\n\n### POST with Request Body\n\n```typescript\napp.post('\u002Fapi\u002Fusers', async (c) => {\n  const body = await c.req.json()\n\n  \u002F\u002F Validate and process body\n  return c.json({ success: true, data: body }, 201)\n})\n```\n\n### Route Parameters\n\n```typescript\napp.get('\u002Fapi\u002Fusers\u002F:id', (c) => {\n  const id = c.req.param('id')\n  return c.json({ id, name: 'User' })\n})\n```\n\n### Query Parameters\n\n```typescript\napp.get('\u002Fapi\u002Fsearch', (c) => {\n  const query = c.req.query('q')\n  return c.json({ query, results: [] })\n})\n```\n\n### Error Handling\n\n```typescript\napp.get('\u002Fapi\u002Fdata', async (c) => {\n  try {\n    \u002F\u002F Your logic here\n    return c.json({ success: true })\n  } catch (error) {\n    return c.json({ error: error.message }, 500)\n  }\n})\n```\n\n### Using Bindings (KV, D1, R2)\n\n```typescript\ntype Bindings = {\n  ASSETS: Fetcher\n  MY_KV: KVNamespace\n  DB: D1Database\n  MY_BUCKET: R2Bucket\n}\n\nconst app = new Hono\u003C{ Bindings: Bindings }>()\n\napp.get('\u002Fapi\u002Fdata', async (c) => {\n  \u002F\u002F KV\n  const value = await c.env.MY_KV.get('key')\n\n  \u002F\u002F D1\n  const result = await c.env.DB.prepare('SELECT * FROM users').all()\n\n  \u002F\u002F R2\n  const object = await c.env.MY_BUCKET.get('file.txt')\n\n  return c.json({ value, result, object })\n})\n```\n\n---\n\n## Static Assets Best Practices\n\n### Directory Structure\n\n```\npublic\u002F\n├── index.html          # Main entry point\n├── styles.css          # Global styles\n├── script.js           # Client-side JavaScript\n├── favicon.ico         # Favicon\n└── assets\u002F             # Images, fonts, etc.\n    ├── logo.png\n    └── fonts\u002F\n```\n\n### SPA Fallback\n\nThe `\"not_found_handling\": \"single-page-application\"` configuration means:\n- Unknown routes return `index.html`\n- Useful for React Router, Vue Router, etc.\n- BUT requires `run_worker_first` for API routes!\n\n### Route Priority\n\nWith `\"run_worker_first\": [\"\u002Fapi\u002F*\"]`:\n\n1. `\u002Fapi\u002Fhello` → Worker handles it (returns JSON)\n2. `\u002F` → Static Assets serve `index.html`\n3. `\u002Fstyles.css` → Static Assets serve `styles.css`\n4. `\u002Funknown` → Static Assets serve `index.html` (SPA fallback)\n\n### Caching Static Assets\n\nStatic Assets are automatically cached at the edge. To bust cache:\n```html\n\u003Clink rel=\"stylesheet\" href=\"\u002Fstyles.css?v=1.0.0\">\n\u003Cscript src=\"\u002Fscript.js?v=1.0.0\">\u003C\u002Fscript>\n```\n\n---\n\n## Development Workflow\n\n### Local Development\n\n```bash\nnpm run dev\n```\n\n- Server runs on http:\u002F\u002Flocalhost:8787\n- HMR enabled (file changes reload automatically)\n- Uses Miniflare for local simulation\n- All bindings work locally (KV, D1, R2)\n\n### Testing API Routes\n\n```bash\n# Test GET endpoint\ncurl http:\u002F\u002Flocalhost:8787\u002Fapi\u002Fhello\n\n# Test POST endpoint\ncurl -X POST http:\u002F\u002Flocalhost:8787\u002Fapi\u002Fecho \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"test\": \"data\"}'\n```\n\n### Type Generation\n\n```bash\nnpm run cf-typegen\n```\n\nGenerates `worker-configuration.d.ts` with:\n- Binding types (KV, D1, R2, etc.)\n- Environment variable types\n- Auto-completes in your editor\n\n### Deployment\n\n```bash\n# Deploy to production\nnpm run deploy\n\n# Deploy to specific environment\nwrangler deploy --env staging\n\n# Tail logs in production\nwrangler tail\n\n# Check deployment status\nwrangler deployments list\n```\n\n---\n\n## Complete Setup Checklist\n\n- [ ] Project scaffolded with `npm create cloudflare@latest`\n- [ ] Dependencies installed: `hono@4.10.1`, `@cloudflare\u002Fvite-plugin@1.13.13`\n- [ ] `wrangler.jsonc` created with:\n  - [ ] `account_id` set to your Cloudflare account\n  - [ ] `assets.directory` pointing to `.\u002Fpublic\u002F`\n  - [ ] `assets.run_worker_first` includes `\u002Fapi\u002F*`\n  - [ ] `compatibility_date` set to recent date\n- [ ] `vite.config.ts` created with `@cloudflare\u002Fvite-plugin`\n- [ ] `src\u002Findex.ts` created with Hono app\n  - [ ] Uses `export default app` (NOT `{ fetch: app.fetch }`)\n  - [ ] Includes ASSETS binding type\n  - [ ] Has fallback route: `app.all('*', (c) => c.env.ASSETS.fetch(c.req.raw))`\n- [ ] `public\u002F` directory created with static files\n- [ ] `npm run cf-typegen` executed successfully\n- [ ] `npm run dev` starts without errors\n- [ ] API routes tested in browser\u002Fcurl\n- [ ] Static assets serve correctly\n- [ ] HMR works without crashes\n- [ ] Ready to deploy with `npm run deploy`\n\n---\n\n## Advanced Topics\n\n### Adding Middleware\n\n```typescript\nimport { Hono } from 'hono'\nimport { logger } from 'hono\u002Flogger'\nimport { cors } from 'hono\u002Fcors'\n\nconst app = new Hono\u003C{ Bindings: Bindings }>()\n\n\u002F\u002F Global middleware\napp.use('*', logger())\napp.use('\u002Fapi\u002F*', cors())\n\n\u002F\u002F Route-specific middleware\napp.use('\u002Fadmin\u002F*', async (c, next) => {\n  \u002F\u002F Auth check\n  await next()\n})\n```\n\n### Environment-Specific Configuration\n\n```jsonc\n\u002F\u002F wrangler.jsonc\n{\n  \"name\": \"my-worker\",\n  \"env\": {\n    \"staging\": {\n      \"vars\": { \"ENV\": \"staging\" }\n    },\n    \"production\": {\n      \"vars\": { \"ENV\": \"production\" }\n    }\n  }\n}\n```\n\nDeploy: `wrangler deploy --env staging`\n\n### Custom Error Pages\n\n```typescript\napp.onError((err, c) => {\n  console.error(err)\n  return c.json({ error: 'Internal Server Error' }, 500)\n})\n\napp.notFound((c) => {\n  return c.json({ error: 'Not Found' }, 404)\n})\n```\n\n### Testing with Vitest\n\n```bash\nnpm install -D vitest @cloudflare\u002Fvitest-pool-workers\n```\n\nCreate `vitest.config.ts`:\n\n```typescript\nimport { defineConfig } from 'vitest\u002Fconfig'\n\nexport default defineConfig({\n  test: {\n    poolOptions: {\n      workers: {\n        wrangler: { configPath: '.\u002Fwrangler.jsonc' },\n      },\n    },\n  },\n})\n```\n\nSee `reference\u002Ftesting.md` for complete testing guide.\n\n---\n\n## File Templates\n\nAll templates are available in the `templates\u002F` directory:\n\n- **wrangler.jsonc** - Complete Worker configuration\n- **vite.config.ts** - Vite + Cloudflare plugin setup\n- **package.json** - Dependencies and scripts\n- **tsconfig.json** - TypeScript configuration\n- **src\u002Findex.ts** - Hono app with API routes\n- **public\u002Findex.html** - Static frontend example\n- **public\u002Fstyles.css** - Example styling\n- **public\u002Fscript.js** - API test functions\n\nCopy these files to your project and customize as needed.\n\n---\n\n## Reference Documentation\n\nFor deeper understanding, see:\n\n- **architecture.md** - Deep dive into export patterns, routing, and Static Assets\n- **common-issues.md** - All 6 issues with detailed troubleshooting\n- **deployment.md** - Wrangler commands, CI\u002FCD patterns, and production tips\n\n---\n\n## Official Documentation\n\n- **Cloudflare Workers**: https:\u002F\u002Fdevelopers.cloudflare.com\u002Fworkers\u002F\n- **Static Assets**: https:\u002F\u002Fdevelopers.cloudflare.com\u002Fworkers\u002Fstatic-assets\u002F\n- **Vite Plugin**: https:\u002F\u002Fdevelopers.cloudflare.com\u002Fworkers\u002Fvite-plugin\u002F\n- **Wrangler Configuration**: https:\u002F\u002Fdevelopers.cloudflare.com\u002Fworkers\u002Fwrangler\u002Fconfiguration\u002F\n- **Hono**: https:\u002F\u002Fhono.dev\u002Fdocs\u002Fgetting-started\u002Fcloudflare-workers\n- **Context7 Library ID**: `\u002Fwebsites\u002Fdevelopers_cloudflare-workers`\n\n---\n\n## Dependencies (Latest Verified 2025-10-20)\n\n```json\n{\n  \"dependencies\": {\n    \"hono\": \"^4.10.1\"\n  },\n  \"devDependencies\": {\n    \"@cloudflare\u002Fvite-plugin\": \"^1.13.13\",\n    \"@cloudflare\u002Fworkers-types\": \"^4.20251011.0\",\n    \"vite\": \"^7.0.0\",\n    \"wrangler\": \"^4.43.0\",\n    \"typescript\": \"^5.9.0\"\n  }\n}\n```\n\n---\n\n## Production Example\n\nThis skill is based on the cloudflare-worker-base-test project:\n- **Live**: https:\u002F\u002Fcloudflare-worker-base-test.webfonts.workers.dev\n- **Build Time**: ~45 minutes (actual)\n- **Errors**: 0 (all 6 known issues prevented)\n- **Validation**: ✅ Local dev, HMR, production deployment all successful\n\nAll patterns in this skill have been validated in production.\n\n---\n\n**Questions? Issues?**\n\n1. Check `reference\u002Fcommon-issues.md` first\n2. Verify all steps in the 4-step setup process\n3. Ensure `export default app` (not `{ fetch: app.fetch }`)\n4. Ensure `run_worker_first` is configured\n5. Check official docs: https:\u002F\u002Fdevelopers.cloudflare.com\u002Fworkers\u002F\n",{"name":5,"license":14,"description":23},"Production-tested setup for Cloudflare Workers with Hono, Vite, and Static Assets.\n\nUse when: creating new Cloudflare Workers projects, setting up Hono routing with Workers,\nconfiguring Vite plugin for Workers, adding Static Assets to Workers, deploying with Wrangler,\nor encountering deployment errors, routing conflicts, or HMR crashes.\n\nPrevents 6 documented issues: export syntax errors, Static Assets routing conflicts,\nscheduled handler errors, HMR race conditions, upload race conditions, and Service Worker\nformat confusion.\n\nKeywords: Cloudflare Workers, CF Workers, Hono, wrangler, Vite, Static Assets, @cloudflare\u002Fvite-plugin,\nwrangler.jsonc, ES Module, run_worker_first, SPA fallback, API routes, serverless, edge computing,\n\"Cannot read properties of undefined\", \"Static Assets 404\", \"A hanging Promise was canceled\",\n\"Handler does not export\", deployment fails, routing not working, HMR crashes\n","main","45d5ac830c3e238eeba6d0b4e6fd7cf6b56bf380","https:\u002F\u002Fgithub.com\u002Fdavidanthonyn\u002Fclaude-skills","https:\u002F\u002Fgithub.com\u002Fdavidanthonyn","2026-09-09 16:05:56",{"source":8,"skillName":5,"commands":30,"prompt":40,"zipAvailable":41},[31,34,37],{"tool":32,"command":33},"npx","npx skills add davidanthonyn\u002Fclaude-skills --skill cloudflare-worker-base",{"tool":35,"command":36},"bunx","bunx skills add davidanthonyn\u002Fclaude-skills --skill cloudflare-worker-base",{"tool":38,"command":39},"pnpm","pnpm dlx skills add davidanthonyn\u002Fclaude-skills --skill cloudflare-worker-base","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fdavidanthonyn\u002Fclaude-skills\u002Fblob\u002Fmain\u002Fcloudflare-worker-base\u002FSKILL.md",true,[43,49,53],{"path":44,"resourceType":45,"resourceTypeDesc":46,"sizeBytes":47,"sourceHtmlUrl":48},"README.md","REFERENCE","参考文档",6552,"https:\u002F\u002Fgithub.com\u002Fdavidanthonyn\u002Fclaude-skills\u002Fblob\u002Fmain\u002Fcloudflare-worker-base\u002FREADME.md",{"path":50,"resourceType":45,"resourceTypeDesc":46,"sizeBytes":51,"sourceHtmlUrl":52},"SKILL.json",19405,"https:\u002F\u002Fgithub.com\u002Fdavidanthonyn\u002Fclaude-skills\u002Fblob\u002Fmain\u002Fcloudflare-worker-base\u002FSKILL.json",{"path":54,"resourceType":55,"resourceTypeDesc":56,"sizeBytes":57,"sourceHtmlUrl":58},"SKILL.md.backup","OTHER","其他",17941,"https:\u002F\u002Fgithub.com\u002Fdavidanthonyn\u002Fclaude-skills\u002Fblob\u002Fmain\u002Fcloudflare-worker-base\u002FSKILL.md.backup",[60,67,75,82,89,98],{"skillNo":61,"name":62,"nameZh":6,"description":63,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":64,"categories":65,"keywords":66,"publishedAt":18},"01M7AQPHJF528A4MD52YZEZV3R","zustand-state-management","Production-tested setup for Zustand state management in React applications with TypeScript.\nThis skill provides comprehensive patterns for building scalable, type-safe global state.\n\nUse when: setting up global state in React, migrating from Redux or Context API, implementing\nstate persistence with localStorage, configuring TypeScript with Zustand, using slices pattern\nfor modular stores, adding devtools middleware for debugging, handling Next.js SSR hydration,\nor encountering hydration errors, TypeScript inference issues, or persist middleware problems.\n\nPrevents 5 documented issues: Next.js hydration mismatches, TypeScript double parentheses\nsyntax errors, persist middleware export errors, infinite render loops, and slices pattern\ntype inference failures.\n\nKeywords: zustand, state management, React state, TypeScript state, persist middleware,\ndevtools, slices pattern, global state, React hooks, create store, useBoundStore,\nStateCreator, hydration error, text content mismatch, infinite render, localStorage,\nsessionStorage, immer middleware, shallow equality, selector pattern, zustand v5","https:\u002F\u002Fgithub.com\u002Fdavidanthonyn\u002Fclaude-skills\u002Fblob\u002Fmain\u002Fzustand-state-management\u002FSKILL.md",[],[],{"skillNo":68,"name":69,"nameZh":6,"description":70,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":71,"sourceHtmlUrl":72,"categories":73,"keywords":74,"publishedAt":18},"01M7AQP2XJRPNYEH323GJ81NN5","zetic-mlange","Help users integrate the ZETIC Melange (MLange) on-device AI SDK into Android (Kotlin\u002FJava) and iOS (Swift) mobile apps. Use this skill whenever the user mentions Zetic, MLange, Melange, ZeticMLangeModel, ZeticMLangeLLMModel, ZeticMLangeHFModel, on-device NPU inference for mobile, or deploying ML models to Android\u002FiOS with NPU acceleration. Also trigger when users ask about running LLMs on-device with GGUF quantization, mobile NPU model deployment, or converting PyTorch\u002FONNX models for mobile inference. Covers general model inference, LLM inference (streaming token generation), and HuggingFace model loading.","https:\u002F\u002Fgithub.com\u002Fdavidanthonyn\u002Fclaude-skills\u002Fblob\u002Fmain\u002Fzetic-mlange\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fdavidanthonyn\u002Fclaude-skills\u002Fblob\u002Fmain\u002Fzetic-mlange\u002FSKILL.md",[],[],{"skillNo":76,"name":77,"nameZh":6,"description":78,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":79,"categories":80,"keywords":81,"publishedAt":18},"01M7AQNEJHD27NNF5PYQDSW8B9","youtube-downloader","Download videos, audio, playlists, and channels from YouTube and 1000+ websites using yt-dlp. Supports quality selection, format conversion, subtitle download, playlist filtering, metadata extraction, thumbnail download, and batch operations. Use when downloading YouTube videos in any quality (4K, 8K, HDR), extracting audio as MP3\u002FM4A\u002FFLAC, downloading entire playlists\u002Fchannels, getting subtitles in multiple languages, converting to specific formats, downloading live streams, archiving content, or batch processing multiple URLs. Optimized for reliability with automatic retries, rate limiting, and error handling.","https:\u002F\u002Fgithub.com\u002Fdavidanthonyn\u002Fclaude-skills\u002Fblob\u002Fmain\u002Fyoutube-downloader\u002FSKILL.md",[],[],{"skillNo":83,"name":84,"nameZh":6,"description":85,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":86,"categories":87,"keywords":88,"publishedAt":18},"01M7AQJQSD2H04EE2EPNAQ8A3M","wordpress-plugin-core","This skill provides comprehensive knowledge for WordPress plugin development, covering core patterns, security best practices, database interactions, hooks\u002Ffilters, Settings API, custom post types, REST API, and AJAX. This skill should be used when creating WordPress plugins, troubleshooting security issues, implementing custom post types\u002Ftaxonomies, building admin interfaces, or working with the WordPress database.\n\nUse when: Creating new WordPress plugins, implementing nonces\u002Fsanitization\u002Fescaping, working with $wpdb and prepared statements, building Settings API pages, registering custom post types or taxonomies, implementing REST API endpoints, handling AJAX requests, debugging plugin activation\u002Fdeactivation issues, preventing SQL injection\u002FXSS\u002FCSRF vulnerabilities.\n\nKeywords: wordpress plugin development, wordpress security, wordpress hooks, wordpress filters, wordpress database, wpdb prepare, sanitize_text_field, esc_html, wp_nonce, custom post type, register_post_type, settings api, rest api, admin-ajax, wordpress sql injection, wordpress xss, wordpress csrf, plugin header, activation hook, deactivation hook, wordpress coding standards, wordpress plugin architecture","https:\u002F\u002Fgithub.com\u002Fdavidanthonyn\u002Fclaude-skills\u002Fblob\u002Fmain\u002Fwordpress-plugin-core\u002FSKILL.md",[],[],{"skillNo":90,"name":91,"nameZh":6,"description":92,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":93,"licenseFileUrl":94,"sourceHtmlUrl":95,"categories":96,"keywords":97,"publishedAt":18},"01M7AQJ91T970QCFMN9R1EHZXV","webapp-testing","Test local web applications with Playwright. Use when asked to verify frontend functionality, debug UI behavior, capture browser screenshots, or inspect browser logs.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fdavidanthonyn\u002Fclaude-skills\u002Fblob\u002Fmain\u002Fwebapp-testing\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fdavidanthonyn\u002Fclaude-skills\u002Fblob\u002Fmain\u002Fwebapp-testing\u002FSKILL.md",[],[],{"skillNo":99,"name":100,"nameZh":6,"description":101,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":102,"categories":103,"keywords":104,"publishedAt":18},"01M7AQJ5E89MS8C5K3GZTY4B48","web-performance-audit","Audit web performance using Chrome DevTools MCP. Use when asked to audit, profile, debug, or optimize page load performance, Lighthouse scores, or site speed.","https:\u002F\u002Fgithub.com\u002Fdavidanthonyn\u002Fclaude-skills\u002Fblob\u002Fmain\u002Fweb-performance-audit\u002FSKILL.md",[],[]]