Cloudflare Workers represent a paradigm shift in how we deploy code. Instead of managing servers, you write a few lines of JavaScript that execute globally on Cloudflare's edge network. No cold starts, no scaling headaches, no servers to maintain. Deploy to 300+ data centers worldwide instantly.
What Are Cloudflare Workers?
A Cloudflare Worker is a JavaScript function that intercepts HTTP requests and generates responses. It runs on Cloudflare's edge network, meaning it executes in data centers close to your users, not in a distant data center.
This architecture enables low-latency responses, reduced bandwidth costs, and simplified deployments. Your code is cached globally. Scaling is automatic.
Setting Up Your First Worker
Install Wrangler, Cloudflare's CLI tool:
npm install -g wranglerCreate a new project:
wrangler init my-worker
cd my-workerYour project structure includes a wrangler.toml configuration file and a src/index.js file.
Your First Worker
Here's a minimal worker that returns "Hello World":
export default {
async fetch(request) {
return new Response("Hello, World!");
}
};Deploy it:
wrangler deployCloudflare assigns your worker a *.workers.dev domain. Your code is now live globally.
Routing and Path Matching
Real workers need to handle different routes. Here's how to structure routing logic:
export default {
async fetch(request) {
const url = new URL(request.url);
const pathname = url.pathname;
if (pathname === "/api/users") {
return handleUsers(request);
}
if (pathname === "/api/posts") {
return handlePosts(request);
}
return new Response("Not found", { status: 404 });
}
};
async function handleUsers(request) {
const data = { users: ["Alice", "Bob", "Charlie"] };
return new Response(JSON.stringify(data), {
headers: { "content-type": "application/json" }
});
}Request Methods and Body Parsing
Handle different HTTP methods and parse request bodies:
export default {
async fetch(request) {
if (request.method === "POST") {
const body = await request.json();
console.log("Received:", body);
return new Response("OK");
}
if (request.method === "GET") {
return new Response("GET request received");
}
return new Response("Method not allowed", { status: 405 });
}
};Connecting to Databases
Cloudflare supports multiple databases. For SQL databases, use Hyperdrive:
export default {
async fetch(request, env) {
const db = env.DB;
const result = await db.prepare(
"SELECT * FROM users WHERE id = ?"
).bind(1).first();
return new Response(JSON.stringify(result), {
headers: { "content-type": "application/json" }
});
}
};For key-value storage, use Durable Objects or KV:
const kv = env.MY_KV_NAMESPACE;
await kv.put("key", "value", { expirationTtl: 3600 });
const value = await kv.get("key");CORS and Headers
Handle CORS for browser-based requests:
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type"
};
export default {
async fetch(request) {
if (request.method === "OPTIONS") {
return new Response(null, { headers: corsHeaders });
}
const response = new Response("API response");
Object.entries(corsHeaders).forEach(([key, value]) => {
response.headers.set(key, value);
});
return response;
}
};Environment Variables
Store secrets in wrangler.toml:
[env.production]
vars = { ENVIRONMENT = "production" }
secret = { API_KEY = "your-secret-key" }
[env.development]
vars = { ENVIRONMENT = "development" }Access them in your worker:
export default {
async fetch(request, env) {
const apiKey = env.API_KEY;
const environment = env.ENVIRONMENT;
// Use them in your code
}
};Caching Strategies
Cache responses to reduce latency:
export default {
async fetch(request, env) {
const cache = caches.default;
const cached = await cache.match(request);
if (cached) {
return cached;
}
const response = await fetch(request);
const cacheControl = response.headers.get("cache-control");
if (cacheControl && cacheControl.includes("public")) {
response.headers.set("cache-control", "max-age=3600");
await cache.put(request, response.clone());
}
return response;
}
};Error Handling
Always wrap operations in try-catch:
export default {
async fetch(request, env) {
try {
const data = await env.DB.prepare("SELECT * FROM users").all();
return new Response(JSON.stringify(data), {
headers: { "content-type": "application/json" }
});
} catch (error) {
console.error("Error:", error);
return new Response("Internal server error", { status: 500 });
}
}
};Logging and Monitoring
Workers integrates with Cloudflare Analytics. Use console.log for debugging:
console.log("Processing request:", request.url);
console.error("Database error:", error);View logs in the Cloudflare dashboard or via wrangler:
wrangler tailDeployment
Deploy to production with a single command:
wrangler deploy --env productionSet up continuous deployment via GitHub Actions for automated deployments on push.
Pricing
Cloudflare Workers offers a generous free tier: 100,000 requests per day. Paid plans scale based on actual usage, typically $0.15 per million requests. For most applications, the free tier is sufficient.
Next Steps
Start with a simple API. Add database connectivity. Implement caching. Build full-stack applications without managing infrastructure. Cloudflare Workers removes operational overhead, letting you focus on building.
🛠 Go Deeper
Resources for serverless and edge computing. Affiliate links support this site.
Learning Serverless (O'Reilly)
Solid foundation for serverless architecture patterns beyond Workers.
Web Development with Node & Express
Understanding Node.js patterns makes you a better edge developer.