Skip to content

Foldkit

Source: src/Cloudflare/Website/Foldkit.ts

A Cloudflare Worker deployed from a Foldkit app.

Foldkit apps are client-only Vite projects, so Foldkit drives the project’s own vite build — the Foldkit Vite plugin in the app’s vite.config.ts composes with the injected Cloudflare plugin — and deploys the client output as static assets. No Wrangler configuration, build command, or output directory required.

Input files are content-hashed (respecting .gitignore by default) so unchanged projects skip the build and deploy entirely.

Foldkit apps route on the client, so assets.notFoundHandling defaults to "single-page-application" — deep links serve index.html and the Foldkit router takes over.

A single call builds the project and deploys the client output as static assets — no configuration required.

Foldkit app

const site = yield* Cloudflare.Website.Foldkit("Website");

Foldkit project in a subdirectory

const site = yield* Cloudflare.Website.Foldkit("Website", {
rootDir: "applications/web",
});

Unmatched paths serve index.html by default so deep links boot the app and the Foldkit router resolves the route. An explicit assets config merges over the default — a site that ships real 404 content can opt out.

const site = yield* Cloudflare.Website.Foldkit("Website", {
assets: {
notFoundHandling: "404-page",
},
});

By default the deployment is assets-only. When code must run at the edge — API routes, error reporting, Durable Object classes — point main at your own module that serves the client build through the ASSETS binding (see FoldkitProps.main). Bindings passed in env are reachable from the entry (and from cron handlers), not from browser code — a Foldkit app runs on the client, so anything it needs must come from a route the Worker serves.

const ticker = yield* Cloudflare.KV.Namespace("Ticker");
const site = yield* Cloudflare.Website.Foldkit("Platform", {
main: "src/worker.ts",
env: {
TICKER: ticker,
},
});

By default, every non-gitignored file is hashed to decide whether a rebuild is needed. Use memo to narrow the scope when your project has large directories that don’t affect the build output.

const site = yield* Cloudflare.Website.Foldkit("Website", {
memo: {
include: ["src/**", "public/**", "package.json"],
},
});

Calling Foldkit with no arguments returns a constructor you can extend to declare the Worker as a named class. The class is both an Effect you can yield* to deploy and a type you can reference elsewhere — useful when other resources need to bind to this Worker.

class Website extends Cloudflare.Website.Foldkit<Website>()("Website") {}
const site = yield* Website;