Cloudflare setup
Use a Cloudflare account and choose a Worker name in goribu.config.js. Deploying to an existing name updates that Worker, so use the name intended for this app.
Log in to Cloudflare from the app directory:
pnpm exec goribu cloudflare-login
- Login command:
goribu cloudflare-logintakes no arguments and needs no app configuration or build. - Login flow: Goribu's installed Wrangler opens browser authorization and stores credentials for later runs.
- Installed Wrangler: Wrangler is a Goribu dependency, so a bare
wranglercommand is usually not on the app's PATH. - Wrangler wrapper: Since 0.9.2, use
pnpm exec goribu wrangler <args>for other Wrangler commands. It uses the account deploy would use; check and deploy repair messages use this form. - Deploy restriction:
goribu wrangler deployis refused because it skips Goribu's build, provisioning, and migrations.--dry-runis allowed. - API token: Supply
CLOUDFLARE_API_TOKENfor non-interactive environments. - Account selection: Set
CLOUDFLARE_ACCOUNT_IDwhen credentials can reach multiple accounts. - Resource permissions: Permissions must cover the Worker and any declared D1 or KV resources.
- Authentication preflight: Deploy validates credentials and account selection before building. It does not start login automatically.
- Authentication repair: Run
pnpm exec goribu cloudflare-loginlocally or repair the token configuration, then retry. - Local commands: Development and
pnpm buildneed no Cloudflare authentication. - Account upgrade check: When upgrading to 0.9.0, confirm the authenticated account before redeploying. Goribu passes it explicitly to Wrangler for secret validation and Worker upload, even when the app's
.envnames a differentCLOUDFLARE_ACCOUNT_ID. - Explicit account override: Set
CLOUDFLARE_ACCOUNT_IDin the shell to select another authorized account.
Preflight checks
pnpm typecheck
pnpm build
pnpm check
pnpm build
pnpm check
- TypeScript check: Skip
pnpm typecheckin JavaScript apps. - Build:
pnpm buildcompiles the application and reports static output. - Deployment plan:
pnpm checkreads the production plan without modifying resources. - Plan contents: The plan includes the Worker name, resource names and bindings, creation or reuse, migration status, and intended production-secrets source.
- Secret values: The plan does not print secret values.
A bare app with no resources may not need Cloudflare access for check; a successful check is not proof of deploy permissions. Deployment performs its own authentication preflight.
Deploy
pnpm run deploy
- Script invocation: Use
pnpm run deploy. Barepnpm deployis a different pnpm command. - Arguments: Goribu's deploy takes no extra arguments.
- Deployment sequence: Deploy builds again, provisions declared resources, applies pending D1 migrations, and uploads the Worker and static assets.
- Public URL: Wrangler prints the public URL.
- Production scope: Deploy changes production; it is not a preview command.
Run the same command for later releases. Verify the deployed URL, the important forms, and any new database behavior after publishing.
- Custom domains: Available in Goribu 0.9.0. An optional
domainin configuration connects an application hostname after Worker upload. Normal Wrangler login works. - Other addresses: Custom-domain attachment preserves other domains and the
workers.devaddress unlessworkersDev: falseis set. - Attachment failure: If hostname attachment fails, the Worker remains deployed and the command reports the connection failure.
Since 0.9.2, deploys turn off Cloudflare's per-version preview URLs, which would only be extra public addresses for a production-only deploy. Existing Workers may show a one-time Wrangler warning about Preview URLs on the next deploy.
Which requests run the Worker
- Route-based execution: Available in Goribu 0.9.3. A deployed app invokes the Worker only for URLs its routes can answer. There is nothing to configure.
- Worker route rules: Build sends each Worker route to the Worker, including
/subscribeand/subscribe/, paths below a parameter such as/posts/*, and Goribu's navigation and R2 endpoints. - Other requests: Static Assets answers all other requests. Probes such as
/wp-login.phpor/.envreceive the app's 404 page without invoking the Worker. - Parameter scope: A parameter covers everything below it.
/posts/42/wp-login.phpstill reaches the Worker and receives the app's 404 page. - Narrow prefixes: Put parameters below a static prefix to keep Worker exposure narrow.
- Root parameters: A root parameter such as
src/routes/[slug].tsxsrc/routes/[slug].jsxcan match any unknown URL. Those apps continue sending unknown URLs to the Worker; build prints a warning naming the route. - Routing limit: Cloudflare allows 100 routing rules. Static files under a parameter, such as
public/posts/feed.xmlunder/posts/*, each need an exclusion. Build fails rather than broadening routing past that limit. - Unknown methods: In production, an unknown URL requested with a method other than GET or HEAD returns
405from Static Assets. - Development routing: Development sends every request to the Worker.
When upgrading to 0.9.3, run pnpm build before deploying. A build can now fail where it passed before; see A 404 page for the 404-related causes.
Live logs
Available in Goribu 0.9.0. Use goribu tail to inspect live Worker requests.
From the app directory, stream live logs from the deployed production Worker named in goribu.config.js. The command uses your Cloudflare login or shell API token without building or deploying:
pnpm exec goribu tail
GET https://app.example.com/hello - 200 OK @ 2026-10-02T10:30:00.000Z
GET https://app.example.com/missing - 404 Not Found @ 2026-10-02T10:30:01.000Z
GET https://app.example.com/boom - 500 Internal Server Error @ 2026-10-02T10:30:02.000Z
- Request status: Live log request lines show the actual HTTP response status, followed by console messages and exceptions.
- Worker outcomes: Worker failures appear separately, such as
[Worker outcome: exception]when background work fails after a response. - Missing status: If Cloudflare supplies no status, the line says
HTTP status unavailable. - Traffic scope: The stream includes all visitors and every hostname connected to the Worker.
- Static requests: Prerendered pages and files served by Static Assets do not appear because they do not invoke the Worker. Since 0.9.3, unknown URLs outside Worker routes are also absent.
- Live-only events: Tail shows live events, not historical logs.
- Stop streaming: Press Ctrl+C to close the stream and remote session. Shutdown errors remain visible.
- Cleanup timeout: If cleanup stalls for 10 seconds, Goribu stops locally and reports that any remaining remote session will expire automatically.
- Piped output: Piped log output remains JSON.
- Tail arguments: Tail takes no arguments or filters.
Provisioning
After configuration, authentication, build, and any secrets-file validation succeed, Goribu prepares resources:
- Create the named D1 database if missing, or reuse the existing one.
- Apply an explicit D1 replication setting, leaving existing policy unchanged when omitted.
- Create or reuse the exact named KV namespace.
- Add the resolved IDs to generated production bindings.
- Verify D1 migration history and apply pending files before Worker upload.
- Ambiguous resources: Resource matching fails rather than choosing an ambiguous match.
- Undeclared resources: Undeclared resources are skipped. A KV-only app has no migration step.
- Data preservation: Deploying code does not erase D1 or KV data.
- Resource selection: Renaming a declaration selects another resource. Removing it does not delete the old resource.
- Local isolation: Local data is never copied to production automatically.
Production secrets
- Secret validation: When
.env.productionexists, a Wrangler dry run validates it and the built Worker before provisioning or migrations. - Secret upload: Deployment uploads that file's keys as Worker secrets and preserves other existing secrets.
Without the file, existing platform secrets remain in use. Local .env is not a fallback. Read Configuration for the distinction between server secrets and public browser values.
Schema changes
Migrations run before the new Worker is uploaded, while the old Worker may still serve traffic. Keep the schema compatible with that old version.
Use an expand-and-contract sequence: add new tables or nullable columns first, deploy code that uses them, stop using the old shape in a later release, then remove it. Do not ship both an additive change and its destructive cleanup as simultaneously pending migrations.
- Early migrations: Use
pnpm exec goribu migrate --remotefor deliberate schema changes before deployment. Deploy still verifies history and applies any other pending migrations. - Migration requirement: There is no
--no-migrationsflag. - Migration failure: A failed migration stops the new Worker upload.
- Partial progress: Created resources and previously applied migration files can remain. The whole deployment is not a transaction. See D1 migrations.
If deployment fails
Read the first error and repair that stage: configuration, authentication, build, secrets, provisioning, migration, or upload. A failed or interrupted command exits non-zero and does not report a successful deployment.
- Output root: Production output lives in
.goribu/dist/. - Browser output:
client/contains HTML, browser assets, and static-navigation data. - Worker output: The Worker environment subdirectory contains its bundle and deployment configuration.
- Build report: A successful
goribu buildprints discovered locations after pre-rendering completes. Public asset URLs stay the same. - Output ownership: Goribu owns output paths and requires cleanup on every build. Remove conflicting output-directory overrides and
emptyOutDir: falsefrom Vite config or plugins. - Old output paths: Update scripts and CI paths referencing root
dist/when upgrading. Goribu leaves that old output untouched. - Environment discovery: Keep
goribu.wrangler.jsoncat the project root for environment-file discovery.
Keep generated .goribu/, .wrangler/, and goribu.wrangler.jsonc out of manual edits. They describe the build, not a second place to configure the app.