Bridge the gap between SvelteKit and Cloudflare Durable Objects
Automatically export your Durable Objects to the Cloudflare Worker bundle generated by @sveltejs/adapter-cloudflare.
When using SvelteKit with Cloudflare's adapter, Durable Object classes need to be exported from the worker entry point (.svelte-kit/cloudflare/_worker.js). However, this file is generated during the build process, making it difficult to include your Durable Objects exports.
The typical error you'll encounter:
[ERROR] Your Worker depends on the following Durable Objects, which are not exported in your entrypoint file
There is a suggested work-around:
https://github.com/sveltejs/kit/issues/13692#issuecomment-3055244347
Unfortunately that is not idempotent. This plugins aims to solve that by setting a marker and making it a Vite plugin so that you don't need to worry about it.
This package provides two ways to automatically add your Durable Objects exports to the worker bundle:
Both methods are idempotent - safe to run multiple times without duplicating exports.
pnpm add -D sveltekit-cloudflare-durable-objects
# or
npm install -D sveltekit-cloudflare-durable-objects
# or
yarn add -D sveltekit-cloudflare-durable-objects
Add the plugin to your vite.config.ts:
import { sveltekit } from '@sveltejs/kit/vite';
import cloudflareDoExporter from 'sveltekit-cloudflare-durable-objects';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
sveltekit(),
cloudflareDoExporter({
// Optional: specify your Durable Object files
// Default: ['src/lib/durable-objects.ts']
durableObjects: ['src/lib/durable-objects.ts']
})
]
});
That's it! The plugin will automatically export your Durable Objects after each build.
Add to your package.json scripts:
{
"scripts": {
"build": "vite build && sveltekit-cloudflare-do"
}
}
Or run directly:
pnpm sveltekit-cloudflare-do
interface DurableObjectsExporterOptions {
/**
* Path(s) to your Durable Object file(s)
* @default ['src/lib/durable-objects.ts']
*/
durableObjects?: string | string[];
/**
* Path to the worker file (relative to project root)
* @default '.svelte-kit/cloudflare/_worker.js'
*/
workerPath?: string;
/**
* Enable verbose logging
* @default false
*/
verbose?: boolean;
}
sveltekit-cloudflare-do [options]
Options:
--help, -h Show help message
--version, -v Show version
--verbose Enable verbose logging
--worker <path> Path to worker file
--do <path> Path to durable object file (can be used multiple times)
You can also configure options in package.json:
{
"sveltekit-cloudflare-do": {
"durableObjects": ["src/lib/durable-objects.ts"],
"workerPath": ".svelte-kit/cloudflare/_worker.js"
}
}
Or in .do-exporter.json:
{
"durableObjects": ["src/lib/durable-objects.ts"],
"workerPath": ".svelte-kit/cloudflare/_worker.js"
}
If you have multiple Durable Object files:
// vite.config.ts
cloudflareDoExporter({
durableObjects: [
'src/lib/durable-objects/chat.ts',
'src/lib/durable-objects/counter.ts',
'src/lib/durable-objects/session.ts'
]
})
// src/lib/durable-objects.ts
import { DurableObject } from 'cloudflare:workers';
export class MyDurableObject extends DurableObject<Env> {
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
}
async fetch(request: Request): Promise<Response> {
return new Response('Hello from Durable Object!');
}
}
// wrangler.jsonc
{
"name": "my-sveltekit-app",
"main": ".svelte-kit/cloudflare/_worker.js",
"durable_objects": {
"bindings": [
{
"name": "MY_DURABLE_OBJECT",
"class_name": "MyDurableObject"
}
]
}
}
// vite.config.ts
import { sveltekit } from '@sveltejs/kit/vite';
import cloudflareDoExporter from 'sveltekit-cloudflare-durable-objects';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
sveltekit(),
cloudflareDoExporter()
]
});
pnpm build
wrangler deploy
After your SvelteKit build completes, this tool:
.svelte-kit/cloudflare/_worker.js)Example of what gets added:
// DURABLE_OBJECTS_EXPORT - do not remove
export * from '../../src/lib/durable-objects.ts';
Make sure you run vite build before the export tool. The plugin handles this automatically.
Ensure your Durable Object class:
DurableObject from 'cloudflare:workers'export class MyDurableObjectGenerate Cloudflare types:
wrangler types
MIT
Issues and pull requests welcome!