AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL unreviewed MIT Self-run

Cloudflare To Bun

skill-daleseo-bun-skills-cloudflare-to-bun · by DaleSeo

Migrate Cloudflare Workers to Bun with runtime compatibility analysis. Use when converting Workers to Bun, migrating from Cloudflare bindings, or moving from edge to server deployment.

No reviews yet
0 installs
34 views
0.0% view→install

Install

$ agentstack add skill-daleseo-bun-skills-cloudflare-to-bun

Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.

Security review

⚠ Flagged

1 finding(s); flagged for manual review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures
  • high Reads credentials/environment and may exfiltrate them.

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Reliability & compatibility

Not yet reviewed
0 installs to date
no reviews yet
8mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Cloudflare To Bun? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Cloudflare Workers to Bun Migration

You are assisting with migrating Cloudflare Workers applications to Bun. This involves converting edge runtime APIs, replacing Cloudflare bindings, and adapting from edge to server deployment.

Quick Reference

For detailed patterns, see:

  • Runtime APIs: [runtime-apis.md](references/runtime-apis.md) - Cloudflare to Bun API mapping
  • Bindings Migration: [bindings.md](references/bindings.md) - KV, R2, D1, Durable Objects replacements
  • Deployment: [deployment.md](references/deployment.md) - Edge to server deployment strategies

Migration Workflow

1. Pre-Migration Analysis

Check current setup:

# Check Cloudflare CLI
wrangler --version

# Check Bun installation
bun --version

# Analyze wrangler.toml
cat wrangler.toml

Review worker configuration:

# Check compatibility flags
grep compatibility_flags wrangler.toml

# Check bindings
grep -E "kv_namespaces|r2_buckets|d1_databases|durable_objects" wrangler.toml

2. Worker Types Analysis

Determine what type of Worker you're migrating:

  • Service Worker: Traditional addEventListener('fetch') format
  • Module Worker: Modern export default { fetch() } format
  • Scheduled Worker: Cron triggers
  • Durable Objects: Stateful objects
  • Pages Functions: Next.js-like file-based routing

3. Runtime API Conversion

Basic Fetch Handler

Cloudflare Worker (Module format):

export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise {
    return new Response('Hello World');
  },
};

Bun Server:

Bun.serve({
  port: 3000,
  fetch(request: Request): Response | Promise {
    return new Response('Hello World');
  },
});

console.log('Server running on http://localhost:3000');
Request/Response Handling

Cloudflare Worker:

export default {
  async fetch(request: Request): Promise {
    const url = new URL(request.url);

    if (url.pathname === '/api/data') {
      return Response.json({ data: 'value' });
    }

    return new Response('Not found', { status: 404 });
  },
};

Bun (with Hono for routing):

import { Hono } from 'hono';

const app = new Hono();

app.get('/api/data', (c) => {
  return c.json({ data: 'value' });
});

app.notFound((c) => {
  return c.text('Not found', 404);
});

export default {
  port: 3000,
  fetch: app.fetch,
};

For complete API mapping, see [runtime-apis.md](references/runtime-apis.md).

4. Bindings Migration

Cloudflare Workers use bindings for KV, R2, D1, etc. These need to be replaced:

KV Namespace → Database/Cache

Cloudflare Worker:

export default {
  async fetch(request: Request, env: Env): Promise {
    const value = await env.MY_KV.get('key');
    await env.MY_KV.put('key', 'value', { expirationTtl: 3600 });

    return Response.json({ value });
  },
};

Bun (using Redis or SQLite):

import { Redis } from 'ioredis';

const redis = new Redis(process.env.REDIS_URL);

Bun.serve({
  async fetch(request: Request) {
    const value = await redis.get('key');
    await redis.setex('key', 3600, 'value');

    return Response.json({ value });
  },
});
R2 Bucket → S3 or File System

Cloudflare Worker:

export default {
  async fetch(request: Request, env: Env): Promise {
    const object = await env.MY_BUCKET.get('file.txt');
    const text = await object?.text();

    return new Response(text);
  },
};

Bun (using S3-compatible storage):

import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';

const s3 = new S3Client({ region: 'us-east-1' });

Bun.serve({
  async fetch(request: Request) {
    const command = new GetObjectCommand({
      Bucket: 'my-bucket',
      Key: 'file.txt',
    });

    const response = await s3.send(command);
    const text = await response.Body?.transformToString();

    return new Response(text);
  },
});

For all bindings replacements, see [bindings.md](references/bindings.md).

5. Environment Variables

Cloudflare Worker (wrangler.toml):

[vars]
API_KEY = "dev-key"

[[env.production.vars]]
API_KEY = "prod-key"

Bun (.env files):

# .env.development
API_KEY=dev-key

# .env.production
API_KEY=prod-key

Access in code:

// Both use the same API
const apiKey = process.env.API_KEY;

6. Configuration Migration

wrangler.toml:

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

[vars]
ENVIRONMENT = "production"

kv_namespaces = [
  { binding = "MY_KV", id = "..." }
]

r2_buckets = [
  { binding = "MY_BUCKET", bucket_name = "my-bucket" }
]

package.json (Bun):

{
  "name": "my-bun-app",
  "type": "module",
  "scripts": {
    "dev": "bun run --hot src/index.ts",
    "start": "bun run src/index.ts",
    "build": "bun build src/index.ts --outdir=dist"
  },
  "dependencies": {
    "hono": "^3.0.0",
    "ioredis": "^5.0.0"
  }
}

7. Routing Patterns

Cloudflare Worker (manual routing):

export default {
  async fetch(request: Request): Promise {
    const url = new URL(request.url);

    if (url.pathname === '/') {
      return new Response('Home');
    }

    if (url.pathname.startsWith('/api/')) {
      return handleApi(request);
    }

    return new Response('Not found', { status: 404 });
  },
};

Bun (with Hono framework):

import { Hono } from 'hono';

const app = new Hono();

app.get('/', (c) => c.text('Home'));

const api = new Hono();
api.get('/users', (c) => c.json({ users: [] }));
app.route('/api', api);

export default {
  port: 3000,
  fetch: app.fetch,
};

8. Scheduled Events (Cron)

Cloudflare Worker:

export default {
  async scheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext) {
    await doCleanup();
  },
};

// wrangler.toml
[triggers]
crons = ["0 0 * * *"]  # Daily at midnight

Bun (using node-cron):

import cron from 'node-cron';

// Run daily at midnight
cron.schedule('0 0 * * *', async () => {
  await doCleanup();
});

// Start server
Bun.serve({
  fetch(request: Request) {
    return new Response('Server running');
  },
});

9. Testing Migration

Cloudflare Worker (Miniflare):

import { Miniflare } from 'miniflare';

const mf = new Miniflare({
  script: `
    export default {
      fetch() { return new Response('Hello'); }
    }
  `,
});

const response = await mf.dispatchFetch('http://localhost/');

Bun Test:

import { describe, test, expect } from 'bun:test';

describe('Server', () => {
  test('should respond to requests', async () => {
    const response = await fetch('http://localhost:3000/');
    expect(response.status).toBe(200);
  });
});

10. Deployment Strategy

Cloudflare Workers:

  • Edge deployment (globally distributed)
  • No cold starts
  • Limited runtime (CPU time limits)
  • Specialized bindings (KV, R2, D1)

Bun Server:

  • Traditional server deployment
  • Self-hosted or cloud (AWS, GCP, Azure)
  • No CPU time limits
  • Standard databases and storage
  • Use Docker for containerization (see bun-deploy skill)

For deployment strategies, see [deployment.md](references/deployment.md).

11. Update package.json

{
  "name": "migrated-from-cloudflare",
  "type": "module",
  "scripts": {
    "dev": "bun run --hot src/index.ts",
    "start": "NODE_ENV=production bun run src/index.ts",
    "test": "bun test",
    "build": "bun build src/index.ts --outdir=dist --minify"
  },
  "dependencies": {
    "hono": "^3.11.0",
    "ioredis": "^5.3.0",
    "@aws-sdk/client-s3": "^3.478.0"
  },
  "devDependencies": {
    "@types/bun": "latest"
  }
}

12. File Structure Migration

Cloudflare Worker:

cloudflare-worker/
├── src/
│   └── index.ts
├── wrangler.toml
└── package.json

Bun Server:

bun-server/
├── src/
│   ├── index.ts
│   ├── routes/
│   └── services/
├── .env.development
├── .env.production
├── package.json
├── tsconfig.json
└── bunfig.toml

Migration Checklist

  • [ ] Bun installed and verified
  • [ ] Worker type identified (service/module/durable)
  • [ ] Bindings mapped to replacements (KV→Redis, R2→S3, etc.)
  • [ ] Environment variables migrated
  • [ ] Routing migrated (manual → framework)
  • [ ] Scheduled tasks migrated (cron triggers)
  • [ ] wrangler.toml converted to package.json
  • [ ] TypeScript configuration created
  • [ ] Dependencies installed with bun install
  • [ ] Tests migrated and passing
  • [ ] Local server running
  • [ ] Deployment strategy planned

Key Differences

| Feature | Cloudflare Workers | Bun Server | |---------|-------------------|------------| | Runtime | Edge (V8 isolates) | Server (JavaScriptCore) | | Deployment | Global edge network | Traditional hosting | | Cold Start | ~0ms | Minimal with Bun | | Execution Time | Limited (CPU time) | Unlimited | | Storage | KV, R2, D1, DO | Redis, S3, PostgreSQL, etc. | | Cost Model | Per-request | Server/container costs | | Scaling | Automatic | Manual/auto-scaling groups | | State | Durable Objects | Traditional databases |

Common Patterns

CORS Handling

Same in both:

const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE',
  'Access-Control-Allow-Headers': 'Content-Type',
};

// Handle OPTIONS preflight
if (request.method === 'OPTIONS') {
  return new Response(null, { headers: corsHeaders });
}

JSON Responses

Same in both:

return Response.json({ data: 'value' }, {
  headers: { 'Cache-Control': 'max-age=3600' }
});

Error Handling

Same in both:

try {
  // Your code
} catch (error) {
  return new Response('Internal Server Error', { status: 500 });
}

Completion

Once migration is complete, provide summary:

  • ✅ Migration status (success/partial/issues)
  • ✅ Bindings replaced (KV→Redis, R2→S3, etc.)
  • ✅ Deployment strategy chosen
  • ✅ Performance comparison
  • ✅ Links to Bun documentation

Next Steps

Suggest to the user:

  1. Set up Redis/database for KV replacement
  2. Configure S3-compatible storage for R2 replacement
  3. Set up monitoring and logging
  4. Plan deployment strategy (Docker, cloud hosting)
  5. Use bun-deploy skill for containerization
  6. Update CI/CD pipelines
  7. Load test the migrated application

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.