mirror of
https://github.com/cloudflare/vinext.git
synced 2026-05-09 08:25:34 +02:00
[GH-ISSUE #80] Pluggable deployment adapters: support Cloudflare, Vercel, Netlify, and custom targets #23
Labels
No labels
enhancement
enhancement
good first issue
help wanted
nextjs-tracking
nextjs-tracking
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/vinext#23
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @southpolesteve on GitHub (Feb 25, 2026).
Original GitHub issue: https://github.com/cloudflare/vinext/issues/80
Problem
vinext deployis currently hard-coded to Cloudflare Workers. The entire deploy pipeline (config generation, dependency installation, build adjustments, and the deploy command itself) lives in a singledeploy.tsfile that only knows about wrangler, Workers, and KV.As vinext grows, people want to deploy to other targets (Vercel, Netlify, generic Node servers). We need a way for deployment providers to plug in without forking the core.
Current state
The good news: the separation is already cleaner than it looks. Six of seven CLI commands are fully provider-agnostic today:
vinext initvinext()vinext checkvinext devvinext buildvinext startvinext lintvinext deployThe Cloudflare-specific code lives in four places:
deploy.ts(~780 lines): Generates wrangler.jsonc, worker entries, installs@cloudflare/vite-pluginandwrangler, builds, callswrangler deployvinext:cloudflare-buildplugin inindex.ts(lines 3058-3204): Post-build hook that injects__VINEXT_SSR_MANIFEST__and__VINEXT_LAZY_CHUNKS__globals into the worker entry, generates_headersfile for immutable asset cachingindex.ts: AhasCloudflarePluginboolean (detected by scanning plugin names forvite-plugin-cloudflare) that controls SSR externals, build manifest, and multi-environment behaviorcloudflare/directory:kv-cache-handler.ts(implements the already-pluggableCacheHandlerinterface),tpr.ts(Traffic-aware Pre-Rendering via Cloudflare analytics API)The cache system (
CacheHandlerinterface inshims/cache.ts) is already fully pluggable. The ISR layer (server/isr-cache.ts) is generic. The production Node server (server/prod-server.ts) has zero Cloudflare code.Proposal: deployment adapters
Following the same pattern used by SvelteKit (
@sveltejs/adapter-cloudflare,@sveltejs/adapter-vercel, etc.) and Astro (@astrojs/cloudflare,@astrojs/vercel, etc.), we introduce a deployment adapter interface.Adapter interface (rough sketch)
Package structure
Separate packages in this monorepo:
User-facing config
The adapter is specified in
vite.config.ts, similar to how SvelteKit does it insvelte.config.js:Then
vinext deployreads the adapter from the resolved config. No CLI argument needed in the common case. If no adapter is configured,vinext deployprints an error telling the user to pick one.What changes in core
DeployAdapterinterface in the vinext core packagehasCloudflarePlugindetection inindex.tswith adapter-driven config: the adapter'sconfigureVite()hook provides the overrides instead of vinext detecting plugins by namevinext:cloudflare-buildinto the Cloudflare adapter'spostBuild()hookdeploy.tsinto@vinext/adapter-cloudflare(the current deploy.ts essentially becomes the adapter)cli.tsto load the adapter from vite config and call itsdeploy()methodvinext buildstays generic: the adapter hooks run at config time and post-build time, sovinext builddoesn't need to know which adapter is in useWhat stays the same
vinext init,vinext check,vinext dev,vinext start,vinext lintare unchangedCacheHandlerinterface is already pluggable (unrelated to this work)server/prod-server.tsremains a pure Node serverserver/isr-cache.tsremains genericOpen questions
How should adapters interact with existing Vite platform plugins?
Cloudflare, Vercel, and Netlify all have their own Vite plugins. Should the adapter:
Option (c) is probably the most pragmatic. The adapter can provide the platform plugin via
vitePlugins()if the user hasn't already added it manually, but also work alongside a manually configured plugin.Should
vinext startbe documented as the "deploy anywhere" solution?For targets that don't have a dedicated deploy platform (Docker, fly.io, Railway, any VPS),
vinext startalready gives you a Node HTTP server. Rather than building adapters for every hosting provider, we could documentvinext startas the universal escape hatch and provide guidance on running it in Docker, systemd, etc.Adapter-specific CLI flags
The current
vinext deployhas Cloudflare-specific flags (--experimental-tpr,--tpr-coverage, etc.). Should adapter-specific flags be:vinext deploy --cloudflare-tprvinext deploy -- --experimental-tpr(everything after--goes to the adapter)vite.config.tsinstead of CLI flags:cloudflare({ tpr: { coverage: 90 } })Option (c) feels cleanest since the adapter is already configured in vite.config.ts.
Implementation plan
DeployAdapterinterface inpackages/vinext/src/adapter.tspackages/adapter-cloudflare/and extract current Cloudflare code into itindex.tsto call adapter hooks instead of checkinghasCloudflarePlugincli.tsdeploy command to load adapter from config@Nsttt commented on GitHub (Feb 25, 2026):
From the Zephyr point of view we will be very interested on making this possible.
We often try to make everything deployable everyone on the bundler level, so its compatible with almost every kind of infra without needing any change.
Worth to mention that for something related to this Nitro comes to mind.
@pi0 commented on GitHub (Feb 26, 2026):
Appreciate that you’re pushing Vinext toward being platform-agnostic ❤️
I opened #82 for adding initial support for the Nitro Vite plugin.
Nitro already provides a solid abstraction layer for deployment providers (Vercel, Cloudflare, Netlify, Deno deploy, AWS, and more) and runtimes such as Node, Bun, and Deno. It natively integrates with Vite tooling (Environments API and RSC) and generates the required platform-specific output files with close to zero overhead.
Instead of building and maintaining multiple adapter systems, I believe positioning Vinext + Nitro together could be a strong move. Nitro already solves the multi-platform deployment layer in a mature way, and collaborating here would help us grow a healthier ecosystem without duplicating work.
We’re fully open to discussion from the Nitro side and happy to explore how we can align our efforts.
@Ethan-Arrowood commented on GitHub (Feb 26, 2026):
Hacking around the Next.js server and build process is a pain point. Excited to see this being addressed front-and-center. Expect Harper to participate and following along closely. Thank you for the excellent work here!