Wrangler bindings

Goribu sets up D1, Postgres, KV and R2 for you. For any other Cloudflare feature, such as Workers AI, a call to another Worker or a Vectorize index, you add Cloudflare's own settings to your config and Goribu passes them through.

added in 0.9.4
On this page

Add a Cloudflare feature

Goribu writes your Wrangler configuration (Workers configuration) from goribu.config.js. Put the extra Wrangler fields in a wrangler block:

goribu.config.js
import { defineConfig } from "goribu/server";

export default defineConfig({
  name: "my-app",
  compatibilityDate: "2026-09-01",
  // Add this
  wrangler: {
    ai: { binding: "AI" },
    services: [{ binding: "SEARCH", service: "search-worker" }],
    vars: { API_HOST: "api.example.com" },
    observability: { enabled: true, head_sampling_rate: 0.1 },
  },
});

Your handlers then read each binding from req.env by the name you gave it:

src/routes/ask.ts
import type { Handler } from "goribu/server";

type Env = {
  AI: { run(model: string, input: { prompt: string }): Promise<{ response?: string }> };
};

export const GET: Handler<Record<string, unknown>, Env> = async (req, res) => {
  const prompt = req.query.get("q") ?? "Say hi in five words";
  const answer = await req.env.AI.run("@cf/meta/llama-3.2-1b-instruct", { prompt });

  return res.json({ answer: answer.response });
};
src/routes/ask.js
export const GET = async (req, res) => {
  const prompt = req.query.get("q") ?? "Say hi in five words";
  const answer = await req.env.AI.run("@cf/meta/llama-3.2-1b-instruct", { prompt });

  return res.json({ answer: answer.response });
};
  • Cloudflare's names: The block uses Wrangler's field names and shapes exactly as Cloudflare documents them, such as ai, services, vectorize, queues.producers, analytics_engine_datasets, browser, vars, observability and limits.
  • Goribu's settings first: Goribu writes its own fields, then adds yours. Always edit goribu.config.js, never the generated goribu.wrangler.jsonc.
  • Resources exist already: Goribu doesn't create what these non-integrated bindings point to. An index, a queue or another Worker must already exist on Cloudflare.
  • Telemetry: Wrangler sends anonymous usage data to Cloudflare by default. Add send_metrics: false to the block to turn it off for this app.

Mistakes are caught early

Every pnpm dev and pnpm build checks the block before Cloudflare sees it, so a typo fails right away instead of being quietly ignored:

Example output
[Goribu] wrangler.observability contains unknown field "head_samplng_rate". Check its spelling against Wrangler's configuration reference. This Goribu installation uses Wrangler 4.127.1; if the field needs a newer Wrangler, update goribu.
  • Plain data only: The block must be JSON. Functions, undefined, Infinity, dates, sparse arrays and circular objects fail with the path to fix, such as wrangler.vars.STARTED_AT.
  • Unknown fields: The whole generated config is checked against the schema that comes with Goribu's Wrangler, including nested fields and array entries such as wrangler.services[0].
  • Wrangler's own rules: Problems like two bindings sharing a name are caught by Wrangler itself and shown as a [Goribu] error.
  • Newer features: Goribu deploys with the Wrangler version it includes, and Wrangler ignores fields it doesn't know yet. The check turns those into errors. If a field from Cloudflare's docs is rejected, update goribu, or use a newer Wrangler yourself.

Use a newer Wrangler

To use a Cloudflare feature before Goribu includes a Wrangler that knows it, override Goribu's Wrangler version in package.json, then run pnpm install:

package.json
{
  "pnpm": {
    "overrides": {
      "wrangler": "4.151.0"
    }
  }
}
  • Everything follows: pnpm dev, pnpm build, pnpm check and pnpm run deploy use that version, and the check reads its schema, so errors name the version you chose.
  • Not tested by Goribu: Goribu relies on some of Wrangler's experimental APIs, which can change between releases. If dev or build breaks, remove the override.
  • Remove it later: Once a Goribu update includes that Wrangler version or newer, delete the override.

What Goribu manages

Some Wrangler fields belong to Goribu. Setting them in the block fails with the reason and where to configure them instead:

FieldsWhy
name, compatibility_date, compatibility_flags, workers_dev, main, assets, preview_urls, account_idSet them with Goribu's own options. CLOUDFLARE_ACCOUNT_ID chooses the account.
d1_databases, kv_namespaces, r2_buckets, hyperdriveUse database, kv and r2. Extra databases, namespaces and buckets aren't supported yet.
routes, route, env, previews, compliance_region, pages_build_output_dirGoribu deploys one production Worker and connects your domain itself.
dev, build, alias, define, minify, rules, no_bundle, tsconfig and other bundling fieldsVite builds your app. Use vite.config.js instead.
triggers, migrations, exports, containers, queues.consumersThey need Worker handlers or exported classes, which Goribu doesn't support yet.
unsafeIt bypasses Wrangler's checks.

Durable Objects and Workflows

You can bind a Durable Object or a Workflow that another Worker defines. Name that Worker with script_name:

goribu.config.js
import { defineConfig } from "goribu/server";

export default defineConfig({
  name: "my-app",
  compatibilityDate: "2026-09-01",
  wrangler: {
    durable_objects: {
      bindings: [{ name: "COUNTER", class_name: "Counter", script_name: "counter-worker" }],
    },
    workflows: [
      { binding: "ONBOARDING", name: "onboarding", class_name: "Onboarding", script_name: "onboarding-worker" },
    ],
  },
});

A class defined in your own app needs exports Goribu doesn't offer yet, so an entry without script_name fails.

Reserved names

ASSETS, DB, KV, R2, R2_PRIVATE, POSTGRES, POSTGRES_CACHED, and any name starting with GORIBU_ or __GORIBU_ belong to Goribu. You can't use them for a binding or a var, even if you don't use the matching feature. That way, adding KV later can never clash with a KV of your own.

Vars and secrets

wrangler.vars is for plain settings, such as an API host or a feature switch. Values can be strings or other JSON, such as numbers or objects.

  • Not for secrets: Vars are written into the deploy config and into your Worker's code, because the Worker imports goribu.config.js. Put API keys in .env.production instead or on your Worker via dashboard directly.
  • Local overrides: In development, the same key in .env or .dev.vars wins over the var.

Placement

Your Worker normally runs in the Cloudflare location closest to each visitor. If a request spends most of its time waiting on one backend, such as your database, placement runs the Worker near that backend instead:

goribu.config.js
import { defineConfig } from "goribu/server";

export default defineConfig({
  name: "my-app",
  compatibilityDate: "2026-09-01",
  wrangler: {
    placement: { mode: "smart" },
  },
});
  • Smart: Cloudflare watches your traffic and moves the Worker only once a closer location proves faster.
  • Your choice: Use { region: "aws:us-east-1" } for a cloud region, { host: "db.example.com:5432" } for a database or other TCP service, or { hostname: "api.example.com" } for an HTTP API. See Cloudflare's placement docs.
  • Static pages: They're still served near the visitor. Placement moves only requests that reach the Worker.
  • Development: pnpm dev runs on your machine, so placement has no effect there.

Development

Most bindings run locally in pnpm dev. Workers AI is different: Cloudflare runs it even while you develop, and so do AI Search, Media, VPC and a few others, plus any binding you mark remote: true.

  • Login needed: When your app declares one of these, pnpm dev first checks your Cloudflare login and uses the same account as deploy. Without a login it stops with an error that names the binding.
  • Fix: Run pnpm exec goribu cloudflare-login, or set CLOUDFLARE_API_TOKEN in CI. With several accounts, set CLOUDFLARE_ACCOUNT_ID.
  • Real usage: Calls made in development reach the real service and count toward your Cloudflare usage.
  • Other Workers: A service binding to a Worker that isn't running on your machine answers with an error until you start that Worker.

Builds and static pages

pnpm build never needs a Cloudflare login. When it prerenders pages, it runs your app without the block's bindings, except vars. The uploaded Worker gets all of them.

  • Vars work: A static page that reads only vars prerenders normally.
  • Bindings don't: A page that calls a binding such as AI while rendering stays on the Worker and is rendered per request.

Check and deploy

pnpm check lists these bindings in their own section, marked as not inspected or managed by Goribu. pnpm run deploy uploads them exactly as written, alongside everything Goribu sets up.

Not supported yet

  • More resources: A second D1 database, KV namespace, R2 bucket or Hyperdrive config.
  • Worker handlers and classes: Cron triggers, queue consumers, your own Durable Objects and Workflows, and containers. Run them in a separate Worker and connect your app to it with services, queues.producers or script_name.
  • Other: Wrangler environments.

If a later version makes Goribu own a field that works today, it will be a breaking change with upgrade notes.