new·Earn with mozg — 20% of every monthSend somebody here and take a fifth of every plan payment they make, for as long as they keep paying — not a bounty on the first invoice. Your handle is the link, the window is thirty days, and the commission lands on your balance the second they pay. Free to join: if you have signed in, you already have the link. mozg.sh/earnall news →
mozg.beta
Sign in

Cloudflare Workers · all subjects

framework guides

71 notes in this subject, read out of this brain and free to use. This is page 1 of 2.

Cloudflare Vite plugin only available in Workers

The Cloudflare Vite plugin is supported in Workers but not in Pages, offering a simpler development experience for Vite-powered frameworks.

File-based routing workaround in Workers

Workers supports popular frameworks, many of which implement file-based routing. Additionally, you can compile your Pages functions/ folder into a Worker using wrangler pages functions build to help ease migration.

Workers Static Assets for new static and full-stack projects

Workers Static Assets is the recommended way to deploy static sites, single-page applications, and full-stack apps on Cloudflare. If you are starting a new project, use Workers instead of Pages. Pages continues to work, but new features and optimizations are focused on Workers. For a purely static site, point assets.directory at your build output—no Worker script is needed. For a full-stack app, add a main entry point and an ASSETS binding to serve static files alongside your API.

Hono framework with cron triggers example

import { Hono } from "hono"; interface Env {} const app = new Hono<{ Bindings: Env }>(); app.get("/", (c) => c.text("Hello World!")); export default { fetch: app.fetch, async scheduled( controller: ScheduledController, env: Env, ctx: ExecutionContext, ) { console.log("cron processed"); }, };

Hono framework with Cron Triggers

A Hono app can handle both regular HTTP requests and Cron Triggers by exporting an object with a fetch property (the Hono app) and an async scheduled property. The scheduled function receives controller (ScheduledController), env (Env), and ctx (ExecutionContext) parameters and uses controller.cron to determine which cron schedule triggered the execution.

vinext: Vite plugin for Next.js on Cloudflare Workers

vinext is a Vite plugin that reimplements the Next.js API surface, allowing you to keep your existing app/, pages/, next.config.js, and public/ directories while using the Vite toolchain. Cloudflare recommends vinext as the default way to run Next.js applications on Cloudflare Workers. vinext is currently in beta.

vinext compatibility check command

Run 'npx vinext check' from your project directory to run a compatibility check before adopting vinext for an existing production application. Review the vinext compatibility dashboard at https://vinext.dev/compatibility for detailed results.

vinext setup paths: three options

There are three ways to set up vinext: (1) use an Agent Skill to inspect and migrate an existing project automatically, (2) use 'vinext init' for a direct CLI setup that keeps your existing Next.js setup working alongside vinext, or (3) use create-cloudflare CLI (C3) with --framework=next to scaffold a new project already configured for Workers.

vinext init: non-destructive migration

The command 'npx vinext init' performs a non-destructive migration. It installs vinext and Vite dependencies, adds vinext scripts, generates the Vite configuration, and creates the Cloudflare Workers configuration. Your existing next dev setup continues to work alongside vinext during testing.

vinext development and build commands

Use 'npm run dev:vinext' to start the vinext development server and 'npm run build:vinext' to build the production output with vinext. Deploy with 'npx @vinext/cloudflare deploy'.

Create new Next.js project for Workers with C3

Run 'npm create cloudflare@latest my-next-app --framework=next' to create a new Next.js project already configured for Cloudflare Workers. C3 creates the project, configures vinext, installs dependencies, and offers to deploy the application. Use 'npm run dev', 'npm run build', and 'npm run deploy' commands.

vinext supported Next.js features

vinext supports: App Router (including layouts, route handlers, metadata, loading, error, and not-found routes), Pages Router (including getStaticProps, getStaticPaths, and getServerSideProps), React Server Components, Server Actions, server-side rendering with streaming, static generation and static export via output: 'export', Incremental Static Regeneration (ISR) using stale-while-revalidate caching, middleware and proxy routes, mostly supported next/* imports, Cloudflare bindings, and partially supported image optimization available at request time.

Access Cloudflare bindings in vinext applications

Import 'env' from 'cloudflare:workers' in server-side application code to access D1, R2, KV, Durable Objects, Workers AI, Queues, Vectorize, and other bindings. Define bindings in your Wrangler configuration and generate types with 'wrangler types' command.

Incremental Static Regeneration in vinext

vinext supports Incremental Static Regeneration (ISR) using a stale-while-revalidate caching model, allowing Workers to serve cached content while refreshing it in the background. Refer to the asynchronous revalidation documentation.

Alternative Next.js deployment paths on Workers

OpenNext adapter can be used when maintaining an existing OpenNext application that cannot yet migrate to vinext due to a compatibility gap. Static Next.js on Pages is available for applications that are static exports and specifically want to deploy to Cloudflare Pages.

Pywrangler CLI tool for Python Workers

Pywrangler is a CLI tool for managing packages and Python Workers. It is a wrapper for wrangler that sets up a full environment, including bundling packages into the worker bundle on deployment.

Pywrangler project setup with pyproject.toml

Create a pyproject.toml file with project name, version, description, requires-python (e.g. >=3.13), dependencies list (e.g. fastapi), and dev dependency-groups containing workers-py and workers-runtime-sdk.

Pywrangler supports all wrangler commands

The pywrangler CLI supports all commands supported by the wrangler tool. Run uv run pywrangler --help for the full list of commands.

Supported Python package types in Workers

Python Workers support pure Python packages and PyEmscripten Python packages from PyPI. Additionally, Python Workers support packages included in Pyodide.

HTTP client library requirements for Python Workers

Only HTTP libraries that can make asynchronous requests are supported in Python Workers. Currently supported libraries are aiohttp and httpx2. Alternatively, use the fetch() API from JavaScript via Python Workers' foreign function interface to make HTTP requests.

PyEmscripten wheels for Python packages

WebAssembly support for Python packages is in early stages and some packages may not be available as PyEmscripten wheels on PyPI. Contact package maintainers to request PyEmscripten wheels or start a thread in the Python Packages Discussions on the Cloudflare Workers Runtime GitHub repository.

Python Workers basic structure

A Python Worker's main entry point is a fetch handler placed in a Default class that extends WorkerEntrypoint, imported from the workers SDK module. The fetch handler is an async method that receives a request and returns a Response.

Minimal Python Worker example

from workers import WorkerEntrypoint, Response class Default(WorkerEntrypoint): async def fetch(self, request): return Response("Hello World!") This shows the simplest Python Worker implementation with a fetch handler that returns a static response.

Python Workers beta compatibility flag

Python Workers are in open beta and require adding the python_workers compatibility flag to your Worker configuration.

Python Workers supported packages

Python Workers support easy installation of packages including FastAPI, Langchain, Pydantic, and more.

Python Workers FFI for Runtime APIs

Python Workers include a foreign function interface (FFI) that lets you use JavaScript objects and functions directly from Python, including all Runtime APIs.

LangChain packages available in Workers runtime

The Workers runtime provides three LangChain Python packages: langchain (version 0.1.8), langchain-core (version 0.1.25), and langchain-openai (version 0.0.6).

LangChain example code structure

The example demonstrates using LangChain with Workers by creating a WorkerEntrypoint class with an async fetch method. It imports PromptTemplate from langchain_core.prompts and OpenAI from langchain_openai. The prompt is created using PromptTemplate.from_template(), an OpenAI instance is initialized with an API key from env, and a chain is created by piping the prompt and llm together with the | operator. The chain is invoked asynchronously using ainvoke() with a dictionary of variables.

Static site deployment with Workers

To deploy a static site on Cloudflare Workers, use C3 (create-cloudflare-cli) to create a new project, run npx wrangler dev to test locally, and run npx wrangler deploy to deploy the project to a *.workers.dev subdomain or custom domain.

Full-stack SSR application deployment with Workers

To deploy a full-stack server-side rendered (SSR) application on Cloudflare Workers, use C3 to create a new project, run npx wrangler dev to test locally, modify src/index.ts for server-side behavior and public/index.html for static assets, then run npx wrangler deploy to deploy.

When to build without a framework

You may prefer to build a website without a framework if you want to learn by implementing core functionalities, are working on a simple project, want to optimize for performance by minimizing dependencies, require complete control over the application, or want to build your own framework.

Static assets file structure

For full-stack applications, the public/ directory contains static assets including public/index.html. Modify content in public/ to change the static assets served by the Worker.

Server-side code file structure

For full-stack applications, the src/index.ts file contains sample code that controls the server-side behavior of the Worker. Modify this file to change how the Worker processes requests.

Static Site Generation (SSG) definition and purpose

Static Site Generation (SSG) applications are web applications which are predominantly built or prerendered ahead-of-time. They are often built with frameworks such as Gatsby or Docusaurus. The build process produces many HTML files and accompanying client-side resources such as JavaScript bundles, CSS stylesheets, images, and fonts. Data is either static, fetched and compiled into the HTML at build-time, or fetched by the client from an API with client-side requests.

SPA example with run_worker_first routing

The following TypeScript Worker example demonstrates handling specific routes with run_worker_first: export default { async fetch(request, env): Promise<Response> { const url = new URL(request.url); if (url.pathname === "/api/name") { return new Response(JSON.stringify({ name: "Cloudflare" }), { headers: { "Content-Type": "application/json" }, }); } return new Response(null, { status: 404 }); }, } satisfies ExportedHandler;

SPA not_found_handling behavior

When assets.not_found_handling is set to "single-page-application", incoming requests that do not match a file in the assets.directory will be served the contents of the /index.html file with a 200 OK status instead of a 404 response.

Build Jamstack todo list tutorial with Workers and KV

This tutorial demonstrates building a full-stack todo list application using Cloudflare Workers for the backend and HTML/CSS/JavaScript for the frontend, with data persisted in Workers KV. The application supports creating, reading, and updating todos through a fetch-based API.

Hono error handler

Use `app.onError((err, c) => {})` to define a global error handler in Hono that catches errors from route handlers and returns error responses.

Hono middleware for context setup

Use the Hono `use('*', async (c, next) => {})` middleware to initialize and add context to all routes. Set values using `c.set(key, value)` and retrieve them with `c.get(key)`.

TypeScript types for Hono Bindings and Variables

Define Hono type parameters as `new Hono<{ Bindings: Bindings, Variables: Variables }>()` where Bindings type includes all available bindings and Variables type includes any values set in middleware.

OpenAI Node API library installation

Install the OpenAI Node API library using `npm install openai` to provide convenient access to the OpenAI REST API in a Node.js or Worker project.

Hono framework for Workers

Hono is a lightweight framework for building Cloudflare Workers applications. It provides interfaces for defining routes and middleware functions.

Hono route parameter access

In Hono route handlers, access query parameters using `c.req.query("paramName")` and return JSON responses using `c.json(data)`.

Turso database query execution in Workers

Execute SQL queries against a Turso database using the client.execute() method. For simple queries, pass the SQL string directly: await client.execute("select * from example_users"). For parameterized queries with user input, use the args array to prevent SQL injection: await client.execute({sql: "insert into example_users values (?)", args: [email]})

Turso database connection in Worker code example

Example Worker code connecting to Turso: import { Client as LibsqlClient, createClient } from "@libsql/client/web"; import { Router, RouterType } from "itty-router"; export interface Env { LIBSQL_DB_URL?: string; LIBSQL_DB_AUTH_TOKEN?: string; router?: RouterType; } export default { async fetch(request, env): Promise<Response> { if (env.router === undefined) { env.router = buildRouter(env); } return env.router.fetch(request); }, } satisfies ExportedHandler<Env>; function buildLibsqlClient(env: Env): LibsqlClient { const url = env.LIBSQL_DB_URL?.trim(); if (url === undefined) { throw new Error("LIBSQL_DB_URL env var is not defined"); } const authToken = env.LIBSQL_DB_AUTH_TOKEN?.trim(); if (authToken === undefined) { throw new Error("LIBSQL_DB_AUTH_TOKEN env var is not defined"); } return createClient({ url, authToken }); } function buildRouter(env: Env): RouterType { const router = Router(); router.get("/users", async () => { const client = buildLibsqlClient(env); const rs = await client.execute("select * from example_users"); return Response.json(rs); }); router.get("/add-user", async (request) => { const client = buildLibsqlClient(env); const email = request.query.email; if (email === undefined) { return new Response("Missing email", { status: 400 }); } if (typeof email !== "string") { return new Response("email must be a single string", { status: 400 }); } if (email.length === 0) { return new Response("email length must be > 0", { status: 400 }); } try { await client.execute({ sql: "insert into example_users values (?)", args: [email], }); } catch (e) { console.error(e); return new Response("database insert failed"); } return new Response("Added"); }); router.all("*", () => new Response("Not Found.", { status: 404 })); return router; }

Turso database query result format

Query results from Turso are returned as objects with properties: columns (array of column names), rows (array of row objects), and rowsAffected (number of affected rows). The rows array contains objects where each key is a column name.

Tool definition structure in OpenAI requests

Each tool in the tools array has: type set to 'function', and a function object containing name (function identifier), description (optional but helps model selection), and parameters (JSON Schema object describing input, including type, properties, and required fields).

OpenAI Chat Completions API call with tools

Call openai.chat.completions.create() with parameters: model (e.g., 'gpt-4o-mini'), messages array containing role and content, tools array defining available functions, and tool_choice set to 'auto' to allow either function calls or normal responses.

Second API call after function execution

After executing tool calls and adding results to messages, make a second call to openai.chat.completions.create() with the updated messages array (including tool results) to get the final response informed by the retrieved data.

OpenAI function calling in Workers overview

OpenAI's function calling feature allows an AI model to intelligently decide when to call a function based on input and respond in JSON format matching the function's signature. You can use this in a Cloudflare Worker to have the model determine URLs, retrieve website content, and return responses informed by real-time web data.

Processing assistant tool_calls in response

Check if assistantMessage has a tool_calls property. Loop through tool_calls array, match function names, parse arguments from toolCall.function.arguments, execute the function, and add results to messages array with role 'tool', tool_call_id, name, and content fields.

Example: read_website_content function implementation

async function read_website_content(url) { console.log("reading website content"); const response = await fetch(url); const body = await response.text(); let cheerioBody = cheerio.load(body); const resp = { website_body: cheerioBody("p").text(), url: url, }; return JSON.stringify(resp); } This function fetches a URL, extracts text from paragraph tags using cheerio, and returns a JSON string containing the website body and URL.

Node.js compatibility required for Postgres.js

Node.js compatibility must be configured for your Workers project to use database drivers including Postgres.js.

Vite plugin automatic client environment detection

The Vite plugin automatically determines whether assets should be included based on whether the client environment has been built. The client environment is built by default if any of these conditions are met: there is an index.html file in the root of the project, build.rollupOptions.input or environments.client.build.rollupOptions.input is specified in the Vite config, there is a non-empty public directory, or the Worker imports assets as URLs.

Vite plugin does not require assets field for static assets

The Vite plugin does not require that you provide the assets field in wrangler.toml in order to enable assets. Assets configuration is only needed if you wish to set routing configuration or enable the assets binding.

Vite plugin automatically populates assets.directory

When running vite build, an output wrangler.json configuration file is generated as part of the build output. The assets.directory field in this file is automatically populated with the path to the client build output. It is therefore not necessary to provide the assets.directory field in the input Worker configuration.

Static Assets with Vite plugin and ctx.access limitation

The Vite plugin can add Static Assets to the generated deployment configuration even when the input Wrangler configuration does not include assets. Workers with Static Assets do not receive ctx.access in the user Worker. This behavior affects frameworks that use the Cloudflare Vite plugin, including TanStack Start.

Configure single-page application not_found_handling in Vite plugin

To configure not_found_handling for a single-page application in wrangler.toml with the Vite plugin, set the assets configuration with not_found_handling set to "single-page-application" so that the fallback will always be the root index.html file.

Vite plugin assets binding fetch example

Assets imported as URLs can be fetched via the assets binding. The binding's fetch method requires a full URL; it is recommended to use the request URL as the base. Example: import myImage from "./my-image.png"; export default { fetch(request, env) { return env.ASSETS.fetch(new URL(myImage, request.url)); } };

Vite plugin moves assets imported as URLs to client output

Assets imported as URLs in a Worker will automatically be moved to the client build output. When running vite build, the paths of any moved assets will be displayed in the console.

Give your agent this brain