agentsclimarketplace

Cloudflare workers and edge computing

Skill hamzabellouch/agent-skills/Infrastructure as Code and Edge/cloudflare-workers-and-edge-computing

Architect, build, and deploy production-grade Cloudflare Workers, Durable Objects, D1, KV, and edge API architectures using Wrangler, TypeScript, and Hono.From its SKILL.md

Install
npx -y skills add hamzabellouch/agent-skills --skill cloudflare-workers-and-edge-computing

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 22 days oldThe repository was created 22 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
  • 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

8.2 KB, ~2.1k tokens by cl100k_base, as published. Nobody here has run it

Cloudflare Workers & Edge Computing Skill Guide

This skill covers end-to-end edge application development, state management, latency optimization, and infrastructure integration using Cloudflare Workers, Cloudflare D1, KV, R2, Durable Objects, Hyperdrive, and Vectorize.


1. Edge Architecture Overview & Storage Topology

graph LR
    User([End User / Client]) <-->|Anycast / Lowest Latency| Worker[Cloudflare Worker Node]
    Worker <-->|Sub-millisecond Read| KV[(Cloudflare KV / Cache API)]
    Worker <-->|Strong Consistency / WebSockets| DO[(Durable Objects)]
    Worker <-->|SQL at the Edge| D1[(Cloudflare D1 Database)]
    Worker <-->|Object Storage| R2[(Cloudflare R2 Storage)]
    Worker <-->|Connection Pooling| HD[(Hyperdrive - Postgres)]

Storage Selection Matrix

Storage ServiceConsistency ModelIdeal Use CaseRead LatencyWrite Latency
Workers KVEventual ConsistencyGlobal read-heavy config, feature flags, static assetsLow (edge-cached)High (propagation delay)
Durable ObjectsSingle-location Strict SerializabilityReal-time collaboration, rate limiting, WebSockets, stateful coordinationUltra-low (local)Ultra-low (local)
Cloudflare D1SQLite / Asynchronous ReplicationRelational web app data, blog databases, user metadataEdge-local readRegional write
HyperdriveRegional DB proxying + CachingFast connection pooling for existing cloud PostgreSQL (AWS RDS, Neon, Supabase)Accelerated connectionOrigin dependent

2. Standard Project Structure (wrangler.jsonc + Hono + TypeScript)

edge-service/
├── src/
│   ├── index.ts           # Worker entry point (Hono API routes)
│   ├── durable/           # Durable Object classes
│   │   └── CounterDO.ts
│   ├── services/          # Business logic & bindings encapsulation
│   │   ├── db.ts          # D1 ORM / Drizzle integration
│   │   └── storage.ts     # R2 / KV helpers
│   └── types.ts           # Env bindings & domain types
├── test/                  # Vitest + Miniflare tests
│   └── index.spec.ts
├── drizzle.config.ts      # D1 Drizzle migrations config
├── package.json
├── tsconfig.json
└── wrangler.jsonc         # Cloudflare Worker configuration

3. Production Configuration (wrangler.jsonc)

{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "edge-api-service",
  "main": "src/index.ts",
  "compatibility_date": "2026-03-01",
  "compatibility_flags": ["nodejs_compat"],

  // KV Namespace Bindings
  "kv_namespaces": [
    {
      "binding": "CACHE_KV",
      "id": "abc1234567890def1234567890def123"
    }
  ],

  // D1 Relational Database Bindings
  "d1_databases": [
    {
      "binding": "DB",
      "database_name": "production-db",
      "database_id": "00000000-0000-0000-0000-000000000000"
    }
  ],

  // Durable Objects Bindings
  "durable_objects": {
    "bindings": [
      {
        "name": "RATE_LIMITER",
        "class_name": "RateLimiterDO"
      }
    ]
  },

  // Migrations for Durable Objects
  "migrations": [
    {
      "tag": "v1",
      "new_classes": ["RateLimiterDO"]
    }
  ],

  // Observability & Tail Logs
  "observability": {
    "enabled": true,
    "head_sampling_rate": 1.0
  }
}

4. Production Application Logic (Hono + Durable Objects + D1)

// src/index.ts
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { logger } from 'hono/logger';

export interface Env {
  CACHE_KV: KVNamespace;
  DB: D1Database;
  RATE_LIMITER: DurableObjectNamespace;
}

// Export Durable Object class
export { RateLimiterDO } from './durable/RateLimiterDO';

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

app.use('*', logger());
app.use('/api/*', cors());

// Middleware: Durable Object Edge Rate Limiter
app.use('/api/*', async (c, next) => {
  const clientIp = c.req.header('cf-connecting-ip') || 'anonymous';
  const id = c.env.RATE_LIMITER.idFromName(clientIp);
  const stub = c.env.RATE_LIMITER.get(id);

  const res = await stub.fetch('http://do/check');
  if (res.status === 429) {
    return c.json({ error: 'Too Many Requests' }, 429);
  }

  await next();
});

// Endpoint: Read with KV Layering + D1 Fallback
app.get('/api/users/:id', async (c) => {
  const userId = c.req.param('id');
  const cacheKey = `user:${userId}`;

  // 1. Check KV Cache
  const cachedUser = await c.env.CACHE_KV.get(cacheKey, { type: 'json' });
  if (cachedUser) {
    return c.json({ source: 'kv-cache', data: cachedUser });
  }

  // 2. Query D1 Relational DB
  const user = await c.env.DB.prepare('SELECT id, name, email, created_at FROM users WHERE id = ?')
    .bind(userId)
    .first();

  if (!user) {
    return c.json({ error: 'User Not Found' }, 404);
  }

  // 3. Populate Cache with TTL (300 seconds)
  await c.env.CACHE_KV.put(cacheKey, JSON.stringify(user), { expirationTtl: 300 });

  return c.json({ source: 'd1-database', data: user });
});

export default app;

Stateful Durable Object Implementation (src/durable/RateLimiterDO.ts)

import { DurableObject } from 'cloudflare:workers';

export class RateLimiterDO extends DurableObject {
  private count: number = 0;
  private lastReset: number = Date.now();

  async fetch(request: Request): Promise<Response> {
    const now = Date.now();
    
    // Reset window every 60 seconds
    if (now - this.lastReset > 60_000) {
      this.count = 0;
      this.lastReset = now;
    }

    this.count++;

    if (this.count > 100) {
      return new Response('Rate Limit Exceeded', { status: 429 });
    }

    return new Response('OK', { status: 200 });
  }
}

5. Testing Edge Workers (Vitest + @cloudflare/vitest-pool-workers)

// test/index.spec.ts
import { describe, it, expect } from 'vitest';
import { env, SELF } from 'cloudflare:test';

describe('Edge API Worker', () => {
  it('should return 404 for non-existent users', async () => {
    const res = await SELF.fetch('http://example.com/api/users/non-existent-id');
    expect(res.status).toBe(404);
    const json = await res.json();
    expect(json).toEqual({ error: 'User Not Found' });
  });

  it('should read from D1 and write to KV cache', async () => {
    // Seed D1 test database
    await env.DB.prepare('INSERT INTO users (id, name, email) VALUES (?, ?, ?)')
      .bind('user-1', 'Alice', '[email protected]')
      .run();

    // First fetch: D1 hit
    const res1 = await SELF.fetch('http://example.com/api/users/user-1');
    expect(res1.status).toBe(200);
    const json1 = await res1.json();
    expect(json1.source).toBe('d1-database');

    // Second fetch: KV cache hit
    const res2 = await SELF.fetch('http://example.com/api/users/user-1');
    expect(res2.status).toBe(200);
    const json2 = await res2.json();
    expect(json2.source).toBe('kv-cache');
  });
});

6. Anti-Patterns & Critical Pitfalls

Anti-PatternOperational RiskProduction Remedy
Using Global Variables for Per-Request StateGlobal variables persist across warm worker invocations and bleed state between different concurrent user requests.Store request context in request handlers or local state wrappers. Use Durable Objects for shared persistent state.
Treating Workers KV like Redis/TransactionsKV has eventual consistency. Writing to KV and reading immediately will lead to stale reads.Use Durable Objects or Cloudflare D1 when strong read-after-write consistency is required.
Unbounded Remote DB FetchingCreating raw TCP connections to remote Postgres/MySQL without connection pooling exhausts database sockets.Use Cloudflare Hyperdrive or serverless HTTP/WebSocket drivers (Neon HTTP client, PlanetScale driver).
Heavy NPM Node.js DependenciesExceeds CPU runtime limits / script bundle size limits.Use web standard APIs (fetch, Crypto, Streams) and lightweight edge-native libraries (Hono, Itty-router).

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Gives 0 of the 12 instructions most containers cloud skills give in ~2.1k tokens

Counted across 607 of the 657 authors here whose files we hold, read 2026-08-07

  • Run containers as a non-root userin 66 of 607, across 46 files
  • Use multi-stage buildsin 53 of 607, across 44 files
  • Use Promise.all for independent operationsin 47 of 607, across 13 files
  • Import directly instead of barrel filesin 46 of 607, across 12 files
  • Use ternary instead of AND for conditionalsin 45 of 607, across 12 files
  • Use Set or Map for O(1) lookupsin 42 of 607, across 10 files
  • Create a .dockerignore filein 41 of 607, across 31 files
  • Read individual rule files for detailsin 39 of 607, across 9 files
  • Copy dependency files before source codein 36 of 607, across 23 files
  • Authenticate server actions like API routesin 35 of 607, across 7 files
  • Use next/dynamic for heavy componentsin 34 of 607, across 9 files
  • Use React.cache for per-request deduplicationin 34 of 607, across 10 files

Said here and by no other author read

  • store request context inside request handlers
  • use durable objects for shared persistent state
  • use durable objects for strong consistency
  • use hyperdrive for postgres connection pooling
  • use lightweight edge-native libraries

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 326,861. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.