Sample demo — fictional persona, built to showcase the template.

2025-12-14

Shipping My First Cloudflare Worker

Cloudflare Workers Backend

The contact form on this site used to hit a tiny Express server on a $5 VPS I was paying for and not really using for anything else. I replaced it with a Cloudflare Pages Function this week, mostly out of curiosity about how much of “a backend” you actually need for something this small. Answer: not much.

What got simpler

  • No server to patch. The VPS needed occasional apt upgrade babysitting for a single endpoint. The Worker just runs.
  • Deploys are part of the same pipeline. The function lives at src/pages/api/contact.ts in the same Astro repo as the frontend — one git push, one deploy, no separate service to keep in sync.
  • Cold starts basically aren’t a thing. V8 isolates instead of containers — I never noticed a cold-start delay in testing, unlike the Express server after it had been idle a while.

What didn’t get simpler

  • No filesystem, no long-running process. Fine for a contact form; would matter a lot for anything doing real background work.
  • Environment variables work differently. Cloudflare Pages Functions expose bindings through the request context rather than process.env, which took a minute to get used to coming from Node.
  • Local dev needs Wrangler. astro dev alone doesn’t fully emulate the Workers runtime — worth running wrangler pages dev against the built output before trusting a deploy.

The actual code

Stripped down, the handler is small enough to paste in full:

export const prerender = false;

export const POST: APIRoute = async ({ request }) => {
  const { name, email, message } = await request.json();
  if (!name || !email || !message) {
    return new Response(JSON.stringify({ error: 'Missing fields' }), { status: 400 });
  }
  // ...validate, then send via an email API...
  return new Response(JSON.stringify({ ok: true }), { status: 200 });
};

For a form that gets a few submissions a week, this is now costing me nothing instead of $5/month, and I have one less server to think about. I wouldn’t reach for it yet for something stateful, but for “small function, triggered occasionally, no persistent state” it’s hard to find a reason not to.

← Back to About

Let's build something

I usually reply within 24 hours.

Get in touch