How to deploy a Base project

Ship a Base worker to Cloudflare, with one description that runs across environments and platforms.

Deploy
AhraJuly 22, 2026

How to deploy a Base project

A Base worker is a Cloudflare worker, so deploying one is deploying to Cloudflare. The framework does not invent its own deployment story; it fits the platform's. What Base adds is that the same worker, described once in its settings, knows how to run in more than one environment, so the gap between "works on my machine" and "running in production" is configuration, not a rewrite.

The two environments

Base recognizes two kinds of environment: development and production. Development is where you run locally and iterate. Production is where the worker serves real traffic. The environment is not a flag you scatter through your code; it is part of the configuration the worker reads, so your code can ask "am I in production?" in one consistent way and behave accordingly. Settings that differ between the two, a hostname, a port, which database it points at, are expressed through configuration keyed by environment, so the difference lives in one place instead of in scattered conditionals.

Where a worker can run

The same Base worker can run in more than one kind of place. The natural home is a Cloudflare worker. It can also run as a Cloudflare durable object, which is the stateful single-instance form, and it can run on plain Node, which is how you run it outside Cloudflare entirely, in a test, in a container, on a server. The worker does not change to move between these; the platform it runs on is part of its configuration, and Base adapts the worker's startup to the platform it finds itself on.

That portability is the quiet benefit. The thing you wrote against the Cloudflare runtime is not welded to it. A Base worker is a worker first and a Cloudflare worker second.

Deploying to Cloudflare

Deployment to Cloudflare goes through Cloudflare's own tooling and a wrangler.toml that describes the worker to the platform: its name, its bindings, the resources it connects to. This is where the abstract settings in your worker meet the concrete resources in your Cloudflare account. A bucket you declared in your object store settings is bound to a real R2 bucket in the wrangler config. A database binding in your settings maps to a real binding name. The settings say what the worker needs; the wrangler config says where those needs are satisfied in your account.

You keep the two in agreement: a binding declared in your settings should have a matching binding in the wrangler config, with the same name. When they agree, the worker that ran locally is the worker that runs at the edge, pointed at real resources instead of local ones.

Many environments, one description

Because the settings carry a notion of which deploy environments they apply to, one worker description can cover more than one deployment target. The worker that runs in development and the worker that runs in production are the same worker, configured differently, not two codebases kept in sync by hand. That is the property you want from a deployment story: the thing you tested is the thing you ship, with only its configuration changed to match where it landed.

The mental model to keep

Deploying a Base worker is deploying a Cloudflare worker, with the framework's help making the same worker run in more than one place. It knows two environments, development and production, and three platforms, Cloudflare worker, Cloudflare durable object, and Node, and it adapts to each through configuration rather than code changes. Deployment to Cloudflare goes through wrangler, where your settings' declared needs meet your account's real resources by matching binding names. One worker, described once, configured per environment, shipped where it is configured to go.