본문으로 건너뛰기
cccskills
무료GitHub에 공개

bun-cloudflare-workers

This skill should be used when the user asks about "Cloudflare Workers with Bun", "deploying Bun to Workers", "wrangler with Bun", "edge deployment", "Bun to Cloudflare", or building and deploying applications to Cloudflare Workers using Bun.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

연동 도구Cloudflare
설치 방법 보기

포함된 파일(1)

  • SKILL.md9.0 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Bun Cloudflare Workers

Build and deploy Cloudflare Workers using Bun for development.

Quick Start

# Create new Workers project
bunx create-cloudflare my-worker
cd my-worker

# Install dependencies
bun install

# Development
bun run dev

# Deploy
bun run deploy

Secure Installation

Scaffolding tools like bunx create-cloudflare download and execute remote code. Before running, follow supply chain security best practices:

  • Block post-install scripts — Bun disables them by default; allow specific packages via trustedDependencies in package.json
  • Cooldown period — Configure minimumReleaseAge in bunfig.toml to wait 7 days for new versions
  • Audit before installing — Run socket package score npm <pkg> or use socket npm install <pkg> to check packages

Load the dependency-upgrade skill for full security configuration including Socket CLI integration, cooldown setup, lockfile validation, and CI enforcement.

Project Setup

package.json

{
  "scripts": {
    "dev": "wrangler dev",
    "deploy": "wrangler deploy",
    "build": "bun build src/index.ts --outdir=dist --target=browser"
  },
  "devDependencies": {
    "@cloudflare/workers-types": "^4.20260408.0",
    "wrangler": "^4.81.0"
  }
}

wrangler.toml

name = "my-worker"
main = "src/index.ts"
compatibility_date = "2024-01-01"

# Use Bun for local dev
[dev]
local_protocol = "http"

# Bindings
[[kv_namespaces]]
binding = "KV"
id = "xxx"

[[d1_databases]]
binding = "DB"
database_name = "my-db"
database_id = "xxx"

Basic Worker

// src/index.ts
export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    const url = new URL(request.url);

    if (url.pathname === "/") {
      return new Response("Hello from Cloudflare Workers!");
    }

    if (url.pathname === "/api/data") {
      return Response.json({ message: "Hello" });
    }

    return new Response("Not Found", { status: 404 });
  },
};

interface Env {
  KV: KVNamespace;
  DB: D1Database;
}

Using Hono

// src/index.ts
import { Hono } from "hono";

type Bindings = {
  KV: KVNamespace;
  DB: D1Database;
};

const app = new Hono<{ Bindings: Bindings }>();

app.get("/", (c) => c.text("Hello Hono!"));

app.get("/api/users", async (c) => {
  const users = await c.env.DB.prepare("SELECT * FROM users").all();
  return c.json(users.results);
});

app.post("/api/users", async (c) => {
  const { name } = await c.req.json();
  await c.env.DB.prepare("INSERT INTO users (name) VALUES (?)").bind(name).run();
  return c.json({ success: true });
});

export default app;

KV Storage

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url);
    const key = url.searchParams.get("key");

    if (request.method === "GET" && key) {
      const value = await env.KV.get(key);
      return Response.json({ key, value });
    }

    if (request.method === "PUT" && key) {
      const value = await request.text();
      await env.KV.put(key, value, { expirationTtl: 3600 });
      return Response.json({ success: true });
    }

    return new Response("Bad Request", { status: 400 });
  },
};

D1 Database

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    // Query
    const { results } = await env.DB.prepare(
      "SELECT * FROM users WHERE active = ?"
    ).bind(1).all();

    // Insert
    const info = await env.DB.prepare(
      "INSERT INTO users (name, email) VALUES (?, ?)"
    ).bind("Alice", "alice@example.com").run();

    // Transaction
    const batch = await env.DB.batch([
      env.DB.prepare("INSERT INTO users (name) VALUES (?)").bind("Bob"),
      env.DB.prepare("INSERT INTO users (name) VALUES (?)").bind("Charlie"),
    ]);

    return Response.json(results);
  },
};

Durable Objects

// src/counter.ts
export class Counter {
  private state: DurableObjectState;
  private value = 0;

  constructor(state: DurableObjectState) {
    this.state = state;
    this.state.blockConcurrencyWhile(async () => {
      this.value = (await this.state.storage.get("value")) || 0;
    });
  }

  async fetch(request: Request): Promise<Response> {
    const url = new URL(request.url);

    if (url.pathname === "/increment") {
      this.value++;
      await this.state.storage.put("value", this.value);
    }

    return Response.json({ value: this.value });
  }
}

// src/index.ts
export { Counter } from "./counter";

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const id = env.COUNTER.idFromName("global");
    const stub = env.COUNTER.get(id);
    return stub.fetch(request);
  },
};
# wrangler.toml
[[durable_objects.bindings]]
name = "COUNTER"
class_name = "Counter"

[[migrations]]
tag = "v1"
new_classes = ["Counter"]

R2 Storage

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url);
    const key = url.pathname.slice(1);

    if (request.method === "GET") {
      const object = await env.BUCKET.get(key);
      if (!object) {
        return new Response("Not Found", { status: 404 });
      }
      return new Response(object.body, {
        headers: { "Content-Type": object.httpMetadata?.contentType || "application/octet-stream" },
      });
    }

    if (request.method === "PUT") {
      await env.BUCKET.put(key, request.body, {
        httpMetadata: { contentType: request.headers.get("Content-Type") || undefined },
      });
      return Response.json({ success: true });
    }

    return new Response("Method Not Allowed", { status: 405 });
  },
};

Development with Bun

Local Development

# Run with wrangler (uses Bun for TypeScript)
bun run dev

# Or directly
bunx wrangler dev

Testing with Bun

// src/index.test.ts
import { describe, test, expect } from "bun:test";

// Mock worker
const worker = {
  async fetch(request: Request) {
    return new Response("Hello");
  },
};

describe("Worker", () => {
  test("returns hello", async () => {
    const request = new Request("http://localhost/");
    const response = await worker.fetch(request);
    expect(await response.text()).toBe("Hello");
  });
});

Miniflare for Testing

import { Miniflare } from "miniflare";

const mf = new Miniflare({
  script: await Bun.file("./dist/index.js").text(),
  kvNamespaces: ["KV"],
});

const response = await mf.dispatchFetch("http://localhost/");
console.log(await response.text());

Build for Production

// build.ts
await Bun.build({
  entrypoints: ["./src/index.ts"],
  outdir: "./dist",
  target: "browser", // Workers use browser APIs
  minify: true,
  sourcemap: "external",
});
bun run build.ts
bunx wrangler deploy

Environment Variables

# wrangler.toml
[vars]
API_URL = "https://api.example.com"

# Secrets (set via CLI)
# wrangler secret put API_KEY
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    console.log(env.API_URL);    // From vars (non-secret, safe to log)
    // Access a Worker secret (NEVER log it — wrangler tail / Logpush persist logs)
    if (env.API_KEY) {
      // use env.API_KEY to call the upstream API
    }
    // ❌ NEVER: console.log(env.API_KEY) — secrets must not appear in logs
    return new Response("OK");
  },
};

Scheduled Workers (Cron)

export default {
  async scheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext): Promise<void> {
    console.log("Cron triggered at:", event.scheduledTime);
    // Perform scheduled task
    await env.DB.prepare("DELETE FROM logs WHERE created_at < ?")
      .bind(Date.now() - 7 * 24 * 60 * 60 * 1000)
      .run();
  },

  async fetch(request: Request, env: Env): Promise<Response> {
    return new Response("OK");
  },
};
# wrangler.toml
[triggers]
crons = ["0 * * * *"]  # Every hour

Common Errors

ErrorCauseFix
Bun API not availableWorkers use V8Use Web APIs only
Module not foundBuild issueCheck bundler config
Script too largeExceeds 10MBOptimize bundle
CPU time exceededLong executionOptimize or use queues

API Compatibility

Workers support Web APIs, NOT Bun-specific APIs:

AvailableNot Available
fetch()Bun.file()
ResponseBun.serve()
Requestbun:sqlite
URLbun:ffi
cryptofs
TextEncoderchild_process

When to Load References

Load references/bindings.md when:

  • Advanced KV/D1/R2 patterns
  • Queue workers
  • Service bindings

Load references/performance.md when:

  • Bundle optimization
  • Cold start reduction
  • Caching strategies

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

100+ animated React components (Aceternity UI) for Next.js with Tailwind. Use for hero sections, parallax, 3D effects, or encountering animation, shadcn CLI integration errors.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

secondsky/claude-skills2312026년 10월 19일 업데이트

Secure API authentication with JWT, OAuth 2.0, API keys. Use for authentication systems, third-party integrations, service-to-service communication, or encountering token management, security headers, auth flow errors.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

secondsky/claude-skills2312026년 10월 19일 업데이트

Creates comprehensive API changelogs documenting breaking changes, deprecations, and migration strategies for API consumers. Use when managing API versions, communicating breaking changes, or creating upgrade guides.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

secondsky/claude-skills2312026년 10월 19일 업데이트

Verifies API contracts between services using consumer-driven contracts, schema validation, and tools like Pact. Use when testing microservices communication, preventing breaking changes, or validating OpenAPI specifications.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

secondsky/claude-skills2312026년 10월 19일 업데이트

Master REST and GraphQL API design principles to build intuitive, scalable, and maintainable APIs that delight developers. Use when designing new APIs, reviewing API specifications, or establishing API design standards.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

secondsky/claude-skills2312026년 10월 19일 업데이트

Implements standardized API error responses with proper status codes, logging, and user-friendly messages. Use when building production APIs, implementing error recovery patterns, or integrating error monitoring services.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

secondsky/claude-skills2312026년 10월 19일 업데이트

secondsky의 스킬 모두 보기

이 스킬의 문제 신고