Skip to content

feat: Cloudflare Vite plugin integration#15627

Draft
teemingc wants to merge 95 commits into
fetchable-dev-environmentfrom
cloudflare-vite-plugin
Draft

feat: Cloudflare Vite plugin integration#15627
teemingc wants to merge 95 commits into
fetchable-dev-environmentfrom
cloudflare-vite-plugin

Conversation

@teemingc

@teemingc teemingc commented Mar 31, 2026

Copy link
Copy Markdown
Member

closes #10496
closes #13692
closes #1712
closes #2963
closes #13300
closes #1519

This PR removes support for Cloudflare Pages and integrates with the Cloudflare Vite plugin. Users can now:

  • Use runtime APIs and bindings locally/remotely during build and preview.
  • Deploy apps unbundled by default (bundling is no longer required; saving a build artifact works again)
  • Write a custom worker entrypoint

TODOs

  • export a fetch handler for adapter-cloudflare
  • analysis in workerd
  • prerender in workerd
  • think about what tests are needed
  • split the PR up into removing Cloudflare Pages support and adding the Cloudflare Vite plugin

Please don't delete this checklist! Before submitting the PR, please make sure you do the following:

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.

Tests

  • Run the tests with pnpm test and lint the project with pnpm lint and pnpm check

Changesets

  • If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running pnpm changeset and following the prompts. Changesets that add features should be minor and those that fix bugs should be patch. Please prefix changeset messages with feat:, fix:, or chore:.

Edits

  • Please ensure that 'Allow edits from maintainers' is checked. PRs without this option may be closed.

@changeset-bot

changeset-bot Bot commented Mar 31, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 8970286

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@sveltejs/adapter-cloudflare Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@svelte-docs-bot

Copy link
Copy Markdown

@rdlogout

Copy link
Copy Markdown

Do we have any timeline on this one?
2 week passed

@teemingc

Copy link
Copy Markdown
Member Author

The team is currently focusing on Svelte async bugs, regressions, security fixes, and remote functions. Even if this were merged, it would have to wait until the whole of SvelteKit 3 is ready before release

await expect(page.locator('#var')).toHaveText(`Var: ${prod_string}VAR`);
});

test('serves static assets with assets path prefix', async ({ page, request }) => {

@teemingc teemingc May 19, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Not really sure how to get this test passing in the Cloudflare environment. Vite doesn't enforce consumers to allow us to run arbitrary code during preview so an alternative might be to have process.env.SVELTEKIT_ASSETS as an override which we set before anything else starts?

stolinski added a commit to syntaxfm/live-tools that referenced this pull request May 28, 2026
…1 (steps 1-3)

Steps 1-3 of docs/jazz-to-cloudflare-migration.md:
- Provision D1 + per-show ShowRoom and singleton ShowDirectory Durable Object
  bindings in wrangler.jsonc; generate binding types (pnpm cf:types).
- Switch SvelteKit to @sveltejs/adapter-cloudflare. Because the released adapter
  (pre sveltejs/kit#15627) writes its worker to wrangler's `main`, a second config
  (wrangler.adapter.jsonc) drives the adapter's output while the real wrangler.jsonc
  `main` is src/worker.ts — a custom entry that imports the built SvelteKit worker,
  re-exports the Durable Objects, and wraps fetch with @sentry/cloudflare.
- Port server Sentry to @sentry/cloudflare; delete instrumentation.server.ts and the
  adapter-node tracing/instrumentation settings.
- Move Better Auth off jazzAdapter to a per-request createAuth(env) factory using the
  Drizzle / drizzle-orm/d1 adapter. Hand-authored D1 schema (auth tables + registry:
  shows/showHosts/hostLinks) with a partial unique index enforcing one live show.
  drizzle-kit migrations applied to local D1.
- DEV_AUTH-gated dev-auth bypass (/dev-login) seeding an admin and a viewer, minting
  real JWKS-signed JWTs (verified: admin is_admin:true, viewer false).
- Repoint auth:schema/db:reset; drop auth:validate. Add cf:types/db:* scripts.

Deviations (documented): raw Durable Objects + WebSocket Hibernation API instead of
PartyServer; wrangler dev against the build is the DO-capable runtime loop instead of
@cloudflare/vite-plugin's vite dev, which cannot run a custom DO-exporting worker entry
with the current SvelteKit adapter. Jazz data path goes dark mid-migration (single
branch, no dual-path), restored on the new stack in steps 4-5.

check/lint/build all green; app + auth verified under wrangler dev via Chrome DevTools.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
aslakhellesoy added a commit to oselvar/sveltekit-add-worker-exports that referenced this pull request Jun 7, 2026
Links the two live upstream tracks: sveltejs/kit#15627 (adapter-cloudflare
adopting @cloudflare/vite-plugin) and the Durable Object / Workflow export
gap in cloudflare/workers-sdk#14013.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@badreddinesaadioui

badreddinesaadioui commented Jun 10, 2026

Copy link
Copy Markdown

tested this PR against a real production app: SvelteKit + a Durable Object (voice agent) exported from the same Worker, WebSockets, Workers AI with remote: true bindings, R2, and a handful of +server.ts endpoints. Today we use @oselvar/sveltekit-add-worker-exports to work around #1712, so this PR is exactly what we've been waiting for. Sharing results in case real-world feedback is useful at this stage.

Setup: installed via pkg.pr.new/@sveltejs/kit@15627 and pkg.pr.new/@sveltejs/adapter-cloudflare@15627, with vite@8.0.16, svelte@5.56.3, @sveltejs/vite-plugin-svelte@7, @cloudflare/vite-plugin@1.x, Node 22. Custom entrypoint per the new docs: main pointing at our own src/worker/index.ts that does import { fetch } from '@sveltejs/adapter-cloudflare/worker', re-exports the DO class, and export default { fetch }.

Findings, in the order we hit them:

  1. vite build fails during the analysis phase:

    Cannot find module 'SERVER' imported from node_modules/.vite-analyse/deps_ssr/@sveltejs_adapter-cloudflare_worker.js
    

    Same error reported above by another tester. Root cause appears to be that when the custom entrypoint imports @sveltejs/adapter-cloudflare/worker, Vite's dep optimizer pre-bundles that module, and the adapter's resolver for the virtual SERVER/MANIFEST ids never runs against the optimized copy. Adding optimizeDeps.exclude: ['@sveltejs/adapter-cloudflare/worker'] in user config (both top-level and ssr) did not help; the analysis server seems to spin up its own config. Maybe the adapter should exclude its own /worker subpath from dep optimization. This currently blocks the custom-entrypoint flow entirely, and since a DO class can only be exported from main, it blocks every Durable Object use case, which is the headline feature for us.

  2. vite dev fails before that with:

    The following environment options are incompatible with the Cloudflare Vite plugin:
    	- "ssr" environment: `resolve.external`: ["@floating-ui/dom","@iconify/types"]
    

    We never set resolve.external; vite-plugin-svelte auto-externalizes those (transitive deps of common Svelte UI libs, @iconify/svelte and svooltip in our case). So dev fails out of the box for apps using ordinary component libraries. Workaround: adding them to ssr.noExternal, after which we hit ReferenceError: exports is not defined from the runner, presumably a CJS dep now being executed raw in workerd. We stopped there.

  3. pkce-challenge (transitive dep of Cloudflare's own agents SDK via the MCP SDK) fails to resolve in the worker build: its exports map only has browser and node conditions, no default, so the workerd-conditions resolve finds nothing. Worked around with a resolve.alias to its browser build. Probably an ecosystem problem rather than this PR's, but anyone building a voice/agents app on Workers will hit it immediately.

  4. Minor setup friction worth documenting for testers: the preview kit imports rolldown at config-load time but doesn't ship it, so on a fresh install the build dies with ERR_MODULE_NOT_FOUND: rolldown until you install it manually. And with Vite 7 still installed (peer range is ^8.0.0, npm only warns with --legacy-peer-deps), the failure mode is a confusing Could not find file "src/routes/.../+server.ts" in Vite manifest for every endpoint rather than a version error.

Happy to re-test on this app as the PR evolves; it exercises pretty much everything at once (DO + WebSockets + remote AI bindings + custom entrypoint), so it's a decent canary.

@teemingc teemingc linked an issue Jun 15, 2026 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment