Skip to content

feat(init): add --name to set the Cloudflare Worker name - #3863

Merged
james-elicx merged 8 commits into
mainfrom
init-name-flag
Oct 12, 2026
Merged

james-elicx merged 8 commits into
mainfrom
init-name-flag

Conversation

@MattieTK

@MattieTK MattieTK commented Oct 11, 2026 •

Copy link
Copy Markdown
Member

Summary

vinext init derives the Worker name from package.json (or the directory name). Tools that run it on a user's behalf have no way to pass a name the user chose. This came up in cloudflare/workers-sdk#16200, where @cloudflare/autoconfig runs vinext init for Next.js 16 projects targeting cf: autoconfig lets the user pick a Worker name (and honours WRANGLER_CI_OVERRIDE_NAME in Workers Builds), but the generated cloudflare.config.ts always used vinext's derived name.

This adds --name <name> to vinext init:

  • Where it applies. The name replaces the derived project name for the Cloudflare setup, so it is used for the Worker in the generated cloudflare.config.ts (or wrangler.jsonc with --legacy-wrangler-cloudflare-init), for the names derived from it (the Response Store Worker and its R2 bucket), and in the deploy:response-store script.
  • Validation. The value (from the CLI or the programmatic API) must be a valid Worker name: lowercase letters, numbers and dashes, no leading or trailing dash, at most 63 characters. It requires --platform=cloudflare, in the same way as --legacy-wrangler-cloudflare-init.
  • Existing config. If the file that holds the Worker name already exists (cloudflare.config.ts, or wrangler.jsonc/wrangler.json in legacy mode), init keeps the Worker name in that file and prints a warning that --name was not applied, since that file may already use the name. The deploy:response-store script then keeps its derived name too, so it doesn't target a Worker the kept config doesn't define.

The flag name matches --name on @vinext/cloudflare deploy. The README and vinext init --help document it.

Tests

  • create-vinext-app (tests/create-vinext-app.test.ts): --name <name> before the app directory, and name through the programmatic createVinextApp() API.
  • Unit (tests/init-platform.test.ts): both flag forms, missing values, invalid names including the 63-character limit, and rejection outside Cloudflare init.
  • Init (tests/init.test.ts): the name is used in cloudflare.config.ts and legacy wrangler.jsonc; the Response Store Worker and deploy:response-store script are named after it; init warns and keeps the existing config's Worker name, in both modes; and invalid names passed programmatically are rejected before any files change.
  • Manual: ran the built CLI against a fresh create-next-app project with --name=storefront-production and checked the generated cloudflare.config.ts, and the invalid-name error. (This ran when an existing config was still an error; that case is now a warning, which tests/init.test.ts covers.)

Merge order

This is one of three related changes:

  1. fix: analyse the project again after framework setup cf#260 (re-analyse the project after setup) can merge at any time. It has no visible effect with the current @cloudflare/autoconfig, but it must be in cf before step 4, otherwise the first cf dev after setup runs next dev rather than vite dev.
  2. feat(init): add --name to set the Cloudflare Worker name #3863 (add --name to vinext init) merges and is released. (this PR)
  3. [autoconfig] Configure Next.js 16 projects with vinext for cf workers-sdk#16200 (use vinext for Next.js 16 on the cf target) is updated to pass the Worker name chosen during setup to vinext init --name and to require the vinext release from step 2. It then merges and @cloudflare/autoconfig is released.
  4. cf bumps @cloudflare/autoconfig to the release from step 3, after fix: analyse the project again after framework setup cf#260 has merged.

vinext init derives the Worker name from package.json, so tools that run it
on a user's behalf, such as @cloudflare/autoconfig, cannot apply a name the
user chose. --name sets the Worker name in generated cloudflare.config.ts or
wrangler.jsonc and in the names derived from it. It fails instead of being
ignored when the config that holds the name already exists.
@pkg-pr-new

pkg-pr-new Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

@vinext/cloudflare

npm i https://pkg.pr.new/@vinext/cloudflare@3863

create-vinext-app

npm i https://pkg.pr.new/create-vinext-app@3863

@vinext/types

npm i https://pkg.pr.new/@vinext/types@3863

vinext

npm i https://pkg.pr.new/vinext@3863

@cloudflare/workers-response-store

npm i https://pkg.pr.new/@cloudflare/workers-response-store@3863

commit: 45f4af0

@github-actions

github-actions Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Performance benchmarks

Compared 45f4af0 against base b22d9ba using alternating same-runner rounds. Next.js was unchanged and skipped.

0 improved · 0 regressed · 7 within ±1.5%

Scenario Framework Baseline Current Change
Client bundle size (gzip) vinext 144.8 KB 144.8 KB ⚫ -0.0%
Client entry size (gzip) vinext 132.6 KB 132.6 KB ⚫ -0.0%
Dev server cold start vinext 2.95 s 2.91 s ⚫ -1.3%
Dev server cold start (large Pages Router app) vinext 29.00 s 28.75 s ⚫ -0.9%
Production build time vinext 3.61 s 3.60 s ⚫ -0.4%
RSC entry closure size (gzip) vinext 133.3 KB 133.7 KB ⚫ +0.3%
Server bundle size (gzip) vinext 236.7 KB 237.3 KB ⚫ +0.2%

View detailed results and traces

🟢 improvement · 🔴 regression · ⚫ change below 1.5% · paired base/head

@github-actions

Copy link
Copy Markdown
Contributor
Example Preview Production Original
app-router-cloudflare preview production
pages-router-cloudflare preview production
app-router-playground preview production original
realworld-api-rest preview production
nextra-docs-template preview production
benchmarks preview production
hackernews preview production original
response-store-demo preview production
workers-cache preview production
kv preview production
static-assets-cache preview production
static-assets-pages preview production
static-assets-pages-i18n preview production
static-export preview production
web preview production

@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues
Please review exact head aa7fe2ee8dcafe8cc8968a05e4d01c8df45f925d without modifying or pushing the branch. Report all actionable findings within your 8-minute time limit.

undefined,
'--legacy-wrangler-cloudflare-init expects true or false when using the "--legacy-wrangler-cloudflare-init=value" form.',
);
const name = parseNameArg(args);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolveInitOptions is also used by runCreateVinextAppCli, but that CLI’s positional scanner does not consume the new space-separated value. As a result, create-vinext-app --name storefront actual-app ... sets parsed.directory to storefront and silently ignores actual-app, while still using storefront as the Worker name. Please add --name to the value-taking flags in packages/create-vinext-app/src/index.ts (and cover this invocation) so the documented --name <name> form works through the shared init flow.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 477c498: create-vinext-app now skips the value after --name when it looks for the app directory, and its --help lists the flag. A new test in tests/create-vinext-app.test.ts runs --name storefront <appPath> ... and checks that cloudflare.config.ts is generated in <appPath> with name: "storefront", and that no storefront directory is created. The test fails on the previous head and passes on this one. The whole file passes (17 tests).

@ask-bonk

ask-bonk Bot commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Review: 1 findings.

Posted 1 inline finding. Targeted tests passed: 263 tests across 3 files.

github run

…rectory

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues
Please review exact head 477c4984b4ea43d7bbe0bd0e7b2e9441abf89ed2 without modifying or pushing the branch. Report all actionable findings within your 8-minute time limit.

Comment thread storefront/package.json Outdated
@@ -0,0 +1,33 @@
{

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The entire top-level storefront/ tree is generated create-vinext-app output from the regression reproduction, and it is neither included by pnpm-workspace.yaml nor referenced by the test suite. Keeping it adds 12 untested application files that can become stale independently of the actual template. Please remove the whole storefront/ directory; the new temp-directory test already preserves this reproduction.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in f3f9566. That directory was generated by mistake when the new test was run against the old parser, which treated storefront as the app directory relative to the repo root. The test itself only writes to its temp directory.

@ask-bonk

ask-bonk Bot commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Since last review: 1 resolved, 0 still open, 1 new.

Posted 1 inline finding. Targeted tests passed: 264 tests across 3 files.

github run

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues
Please review exact head f3f95668ea49be50e8142ae461e6342bc29b19ba without modifying or pushing the branch. Report all actionable findings within your 8-minute time limit.

if (arg.startsWith("-")) {
if (
arg === "--platform" ||
arg === "--name" ||

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CLI now supports --name, but the local CloudflareInitOptions used by the exported createVinextApp() signature still has no name?: string. Because this package publishes dist/index.d.ts, TypeScript consumers of the programmatic API cannot request the same custom Worker name: an object literal under initOptions.cloudflare is rejected even though the runtime shared type supports it. Please add name?: string here (or reuse the shared exported option type) and cover the programmatic call.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 1654f77: create-vinext-app's CloudflareInitOptions now has name?: string, matching the shared type. A new test calls createVinextApp() with an inline cloudflare: { ..., name: "storefront" } literal and checks the generated cloudflare.config.ts. Without the type change, vp check rejects that literal with TS2353. The CLI test now also mocks process.cwd() to its temp directory, so a parser regression can't write into the repo. All 18 tests in the file pass.

@ask-bonk

ask-bonk Bot commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Since last review: 1 resolved, 0 still open, 1 new.

Posted 1 inline finding about the public createVinextApp() type missing name.

github run

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues
Please review exact head 1654f77c463ba468c4ad5f2e8d5a0d01fae191b0 without modifying or pushing the branch. Report all actionable findings within your 8-minute time limit.

legacyWrangler?: boolean;
prerender?: boolean;
/** Worker name for generated config, instead of one derived from package.json. */
name?: string;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The newly supported programmatic path does not pass through parseNameArg, so this public option can still contain uppercase characters, spaces, leading/trailing dashes, or more than 63 characters. createVinextApp() forwards initOptions directly to init(), and init() uses the value to generate the Worker config and Response Store resource/script names without validating it. Please move/reuse the Worker-name validation at the shared init boundary (before any files are changed) and cover invalid programmatic input; otherwise the stated Worker-name contract only holds for CLI callers.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in df0ae3c. The Worker-name check is now a shared validateWorkerName() in init-platform.ts. parseNameArg uses it, and so does validateCloudflarePlatformSetup, which runs before init() changes any files. That covers programmatic callers like createVinextApp(). A new tests/init.test.ts case passes "", Storefront, store front, -storefront and a 64-character name through init(). Each one is rejected and leaves the project unchanged. All 5 cases fail without the boundary check. tests/init.test.ts (193 tests) and tests/init-platform.test.ts (59) pass.

@ask-bonk

ask-bonk Bot commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Review: 1 findings.

Posted 1 actionable inline finding. No branch changes made.

github run

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues
Please review exact head df0ae3c081841066dff1282d8f4c413485f4aaf0 without modifying or pushing the branch. Report all actionable findings within your 8-minute time limit.

@ask-bonk

ask-bonk Bot commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Since last review: 1 resolved, 0 still open, 0 new.

LGTM! Targeted tests passed: 270 tests across 3 files.

github run

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues
Please review exact head d1a864bd651aae4d560ddab35ffbc4594bd0b236 without modifying or pushing the branch. Report all actionable findings within your 8-minute time limit.

Comment thread packages/vinext/src/init.ts Outdated
warmCdnCache: options.cloudflare?.warmCdnCache ?? false,
legacyWrangler: options.cloudflare?.legacyWrangler,
scriptNames: options.scriptNames,
workerName: options.cloudflare?.name,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existing cloudflare.config.ts is now authoritative and the warning says --name was not applied, but this still forwards the requested name to addScripts(). With Response Store service-binding enabled and no existing deploy:response-store script, line 278 therefore creates a command targeting <requested-name>-response-store even though the retained config exports a differently named auxiliary Worker. That command will deploy the wrong/nonexistent build target. Please avoid using --name for this script when configKeepingWorkerName is set (or derive the effective auxiliary name from the existing config), and cover this existing-config + Response Store combination.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in c28d97e. When an existing config keeps its Worker name, init() no longer passes --name to addScripts(), so deploy:response-store uses the derived name, as it did before --name existed. A new test in tests/init.test.ts covers an existing cloudflare.config.ts + Response Store service-binding + --name. It asserts the exact script, and on the previous head it fails with --worker storefront-production-response-store. All 194 tests in the file pass.

@ask-bonk

ask-bonk Bot commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Review: 1 findings.

Posted 1 inline finding. Targeted tests passed: 270 tests across 3 files.

github run

… not applied

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues
Please review exact head c28d97e6a1bca4ea0440533aa61fbca259f4c804 without modifying or pushing the branch. Report all actionable findings within your 8-minute time limit.

responseStoreMode?: InitResponseStoreMode;
warmCdnCache?: boolean;
legacyWrangler?: boolean;
/** Worker name for generated config, instead of one derived from package.json. */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The programmatic API now accepts name, but createVinextApp() calls writeTemplate() before init() reaches validateWorkerName(). An invalid name therefore creates the full project and then throws, leaving a non-empty directory that blocks a corrected retry. Please validate this option before writeTemplate() (and cover that invalid input leaves the target absent or empty), so the public API has the same preflight guarantee as direct init().

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 45f4af0. createVinextApp() now validates initOptions.cloudflare.name with the shared validateWorkerName() alongside its other preflight checks, before writeTemplate(). A new test passes name: "Storefront" and asserts that the call rejects and the target directory doesn't exist. On the previous head that test fails because the directory gets created. All 19 tests in tests/create-vinext-app.test.ts pass.

@ask-bonk

ask-bonk Bot commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Since last review: 1 resolved, 0 still open, 1 new.

Posted 1 actionable inline finding. No branch changes made.

github run

…emplate

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues
Please review exact head 45f4af05034ab10fbc84cc185162bb134f22a253 without modifying or pushing the branch. Report all actionable findings within your 8-minute time limit.

}
// init() validates this too, but only after the template is written.
const workerName = options.initOptions.cloudflare?.name;
if (workerName !== undefined) validateWorkerName(workerName);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This preflight validates the name syntax, but it still accepts a valid name when initOptions.platform is "node". The public ResolvedInitOptions shape permits { platform: "node", cloudflare: { ..., name: "storefront" } }; writeTemplate() then creates the full Node project and init() silently ignores the Cloudflare options, whereas the CLI rejects the same combination with --name requires --platform=cloudflare. Please reject this combination before writing the template, and enforce the same invariant at the shared init() boundary for direct programmatic callers.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Declining this one. When init() and createVinextApp() are called with platform: "node", they already ignore every cloudflare option, including legacyWrangler, which the CLI also rejects on Node. name follows the same rule. The --platform=cloudflare requirement is enforced where options are resolved from flags (resolveInitOptions), as it is for --legacy-wrangler-cloudflare-init. Enforcing it for programmatic callers would change how all Cloudflare options are handled, so it's out of scope for this PR.

@ask-bonk

ask-bonk Bot commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Since last review: 1 resolved, 0 still open, 1 new.

Posted 1 inline finding. All 272 targeted tests passed.

github run

@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues
Please review exact head 45f4af05034ab10fbc84cc185162bb134f22a253 without modifying or pushing the branch. Report all actionable findings within your 8-minute time limit.

@ask-bonk

ask-bonk Bot commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Since last review: 1 resolved, 0 still open, 0 new.

LGTM!

github run

@james-elicx
james-elicx merged commit 0ce053d into main Oct 12, 2026
95 checks passed
@james-elicx
james-elicx deleted the init-name-flag branch October 12, 2026 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants