
Cloudflare Worker Builder
Scaffold a Cloudflare Worker with Hono, Wrangler dev/deploy scripts, Vitest pool workers, and static assets plus SPA-style API routing.
Overview
Cloudflare Worker Builder is an agent skill for the Build phase that scaffolds a Hono-based Cloudflare Worker with Wrangler, Vitest, and static assets plus API test hooks.
Install
npx skills add https://github.com/jezweb/claude-skills --skill cloudflare-worker-builderWhat is this skill?
- Wrangler-driven dev, deploy, cf-typegen, and Vitest with @cloudflare/vitest-pool-workers
- Hono routing for hello, data, echo POST, and health API endpoints
- Static assets with run_worker_first so the Worker handles API before SPA fallback
- Sample package.json pins wrangler ^4.54, hono ^4.11, vite ^7.3, typescript ^5.9
- Browser test page buttons to exercise /api/hello, /api/data, /api/echo, /api/health
- 4 sample API test buttons: /api/hello, /api/data, /api/echo, /api/health
Adoption & trust: 1k installs on skills.sh; 841 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You want APIs on Cloudflare Workers but struggle to combine Hono routes, asset serving, run_worker_first, and a testable Wrangler project layout.
Who is it for?
Indie builders shipping edge APIs, lightweight BFFs, or SaaS backends on Cloudflare with TypeScript and Hono.
Skip if: Teams standardized on AWS Lambda-only, heavy relational backends on Workers without D1/R2 planning, or pure static sites with no Worker logic.
When should I use this skill?
Use when scaffolding or extending a Cloudflare Worker + Hono app with Wrangler dev/deploy, Vitest pool workers, and static assets with API-first routing.
What do I get? / Deliverables
You get a deployable Worker project with API routes, static asset fallback, and local Vitest coverage ready to extend with your product logic.
- wrangler-ready Worker project with Hono routes
- Local dev and deploy scripts plus API smoke-test page
Recommended Skills
Journey fit
Canonical shelf is Build → backend because the skill assembles the edge runtime, API routes, and deployment toolchain for the product. Backend subphase fits Workers that serve APIs, health checks, echo routes, and asset fallbacks on Cloudflare’s edge.
How it compares
Edge scaffold skill with Wrangler and Hono—not a managed Terraform/IaC module and not a generic Node Express generator.
Common Questions / FAQ
Who is cloudflare-worker-builder for?
Solo and indie developers using Claude Code or similar agents to stand up Cloudflare Workers with Hono, tests, and static assets in one repo.
When should I use cloudflare-worker-builder?
During Build when you are creating or extending edge APIs, wiring run_worker_first for SPA plus API, or need Wrangler dev/deploy and Vitest pool workers in the same template.
Is cloudflare-worker-builder safe to install?
It is a project template skill; review the Security Audits panel on this Prism page and audit dependencies and Wrangler secrets before deploying to production accounts.
SKILL.md
READMESKILL.md - Cloudflare Worker Builder
{ "name": "cloudflare-worker-base-test", "version": "0.0.0", "private": true, "scripts": { "deploy": "wrangler deploy", "dev": "wrangler dev", "start": "wrangler dev", "test": "vitest", "cf-typegen": "wrangler types" }, "devDependencies": { "@cloudflare/vite-plugin": "^1.17.1", "@cloudflare/vitest-pool-workers": "^0.11.1", "typescript": "^5.9.3", "vite": "^7.3.0", "vitest": "^4.0.0", "wrangler": "^4.54.0" }, "dependencies": { "hono": "^4.11.3" } } <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Cloudflare Worker + Hono + Static Assets</title> <link rel="stylesheet" href="/styles.css"> </head> <body> <div class="container"> <header> <h1>🔥 Cloudflare Worker + Hono + Static Assets</h1> <p>Testing API routes with Workers Static Assets and SPA fallback</p> </header> <section class="test-section"> <h2>API Tests</h2> <p>These API routes are handled by the Worker thanks to <code>run_worker_first</code> configuration.</p> <div class="test-group"> <button onclick="testHello()">Test /api/hello</button> <button onclick="testData()">Test /api/data</button> <button onclick="testEcho()">Test /api/echo (POST)</button> <button onclick="testHealth()">Test /api/health</button> </div> <div id="results"> <h3>Results:</h3> <pre id="output">Click a button to test the API...</pre> </div> </section> <section class="info-section"> <h2>✅ What This Demonstrates</h2> <ul> <li><strong>Static Assets</strong>: This HTML is served from <code>public/</code></li> <li><strong>API Routes</strong>: <code>/api/*</code> routes are handled by Worker first</li> <li><strong>SPA Fallback</strong>: Unknown routes return this index.html</li> <li><strong>Hono Framework</strong>: Type-safe routing with JSON responses</li> <li><strong>ES Module Format</strong>: Correct export pattern prevents build errors</li> </ul> </section> <footer> <p> 📚 <a href="https://developers.cloudflare.com/workers/static-assets/">Static Assets Docs</a> | <a href="https://hono.dev/docs/getting-started/cloudflare-workers">Hono Docs</a> | <a href="https://developers.cloudflare.com/workers/vite-plugin/">Vite Plugin Docs</a> </p> </footer> </div> <script src="/script.js"></script> </body> </html> /** * API Test Functions * * These functions call the Worker API routes and display the results. * Notice how API routes work seamlessly with static assets thanks to * the "run_worker_first" configuration in wrangler.jsonc */ const output = document.getElementById('output') function displayResult(data, status = 200) { const formatted = JSON.stringify(data, null, 2) output.textContent = `Status: ${status}\n\n${formatted}` output.style.borderLeft = status === 200 ? '4px solid #4caf50' : '4px solid #f44336' } function displayError(error) { output.textContent = `Error: ${error.message}\n\nCheck console for details.` output.style.borderLeft = '4px solid #f44336' console.error('API Error:', error) } async function testHello() { try { const response = await fetch('/api/hello') const data = await response.json() displayResult(data, response.status) } catch (error) { displayError(error) } } async function testData() { try { const response = await fetch('/api/data') const data = await response.json() displayResult(data, response.status) } catch (error) { displayError(error) } } async function testEcho() { try { const payload = { test: 'data', timestamp: new Date().toISOString(), random: Math.random(), } const response = await fetch('/api/echo', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(payload), }) const data = await response.json() displayResult(data, response.status) } catch (error) { displayError(error) } } async function testHealth() {