stnd.buildSTANDARD MANUAL2026-08-08
STD-STND-CLO

@stnd/cloudflare

@stnd/cloudflare

Edge-first deployment utilities and integrations for Cloudflare.

ELI5

Two unrelated jobs live here because they’re both “Cloudflare-specific plumbing no app should have to rewrite”:

  1. Image helpers — build a resized/optimized image URL without hand-rolling
    Cloudflare’s URL query params.
  2. ssrDepsPlugin — a dev-only fix so astro dev doesn’t randomly 504 on
    Cloudflare’s local runtime (Workers dev server gets confused if it discovers dependencies one at a time; this pre-declares them all up front).

Install: already included when you use @stnd/core.

Use it (images):

Usage

import { buildCloudflareImageUrl } from "@stnd/cloudflare";
const url = buildCloudflareImageUrl("/my-image.jpg", { width: 800 });

Use it (the dev-server fix, in astro.config.mjs): see the ssrDepsPlugin section below — you only need this if astro dev is misbehaving on Cloudflare.

Overview

@stnd/cloudflare provides the infrastructure for deploying and running Standard applications on the Cloudflare edge. It includes an Astro integration for orchestrating Cloudflare-specific features like image optimization, KV bindings, and Pages Functions.

Features

  • Image Optimization: Automatic integration with Cloudflare Images for high-performance delivery.
  • Pages Functions Orchestration: Simplifies the management of serverless functions on Cloudflare Pages.
  • KV Store Integration: Easy access to Cloudflare KV for session management and caching.
  • D1 & R2 Ready: Foundational support for Cloudflare’s SQL database and object storage.

Astro Integration

Add it to your astro.config.mjs:

import { defineConfig } from "astro/config";
import cloudflare from "@astrojs/cloudflare";
import standard from "@stnd/core";
import stndCloudflare from "@stnd/cloudflare";

export default defineConfig({
  adapter: cloudflare(),
  integrations: [
    standard(),
    stndCloudflare({
      images: { enabled: true, quality: 85, format: "auto" },
      functions: { enabled: false },
    }),
  ],
});

Manual Usage

The image helpers are named exports:

import { buildCloudflareImageUrl, generateImageSrcset } from "@stnd/cloudflare";

const optimizedUrl = buildCloudflareImageUrl("/my-image.jpg", { width: 800 });
const srcset = generateImageSrcset("/my-image.jpg", { widths: [400, 800, 1200] });

Also exported: shouldUseCloudflareImage, generateBlurPlaceholder, and the CloudflareImage / CloudflarePicture / ResponsiveImage component helpers.

SSR dependency pre-bundling (ssrDepsPlugin)

Dev-only Vite plugin that pre-declares SSR dependencies for the Cloudflare Workers module runner, preventing the first-request re-optimization crashes (504 / “file does not exist”). It owns the framework deps every Standard-on-Cloudflare app needs; the app passes its own deps in — keeping app-specific knowledge in the app (no assumption bleed).

// astro.config.mjs
import { ssrDepsPlugin } from "@stnd/cloudflare";

export default defineConfig({
  vite: {
    plugins: [
      ssrDepsPlugin({
        ssrInclude: ["better-auth", "stripe"], // your server-side deps
        clientInclude: ["codemirror", "p5"], // your client-side deps
      }),
    ],
  },
});

Status

Formerly flagged for possible removal — kept: it now owns image optimization and ssrDepsPlugin, which are real, used jobs. The image/functions/comments config surface is still worth an audit for what’s actually wired.

Notes / Observations

(jot down anything noticed here — quirks, gotchas, ideas)

Todo

  • [ ] Audit which of the image/functions/comments config options in [priority:: 3] [token_scale:: 3] [created:: 2026-07-14] [area:: framework]
    integration.js are actually wired vs. vestigial.
  • [ ] Watch Vite’s experimental.bundledDev — this is the real exit from hand-maintaining FRAMEWORK_SSR / FRAMEWORK_CLIENT in ssr-deps.js. The Vite maintainer who added ignoreOutdatedRequests (vitejs/vite#21364) called it a temporary workaround and named full-bundle mode as the fix; @cloudflare/vite-plugin 1.48–1.50 added support for it. Experimental on both sides — re-evaluate when either goes stable, then delete the lists. [priority:: 2] [token_scale:: 3] [created:: 2026-08-07] [area:: framework]
  • [ ] Do not default imageService to cloudflare-binding here. Recorded as a decision, not a task to do: baking one app’s image strategy into the shared integration is assumption bleed. Apps choose their own; @stnd/cloudflare stays neutral. Delete this line once it is written into the framework doctrine doc. [priority:: 1] [token_scale:: 1] [created:: 2026-08-07] [area:: framework]