This project is a simple guestbook application built following the steps outlined in Cloudflare Workers, SvelteKit, Drizzle, and D1: Up and Running
It demonstrates how to build and deploy a full-stack SvelteKit application leveraging Cloudflare's serverless ecosystem, including:
The result is a fast, globally distributed application with potentially zero infrastructure costs thanks to Cloudflare's generous free tiers.
npm
or yarn
can also be used)npm
/yarn
and adjust commands accordingly).wrangler login
).Clone the repository:
git clone https://github.com/jillesme/cloudflare-worker-svelte-guestbook.git
cd cloudflare-worker-svelte-guestbook
Install dependencies:
pnpm install
Set up local database environment:
Create a .env
file in the root of the project and add the following line. This tells Drizzle where to find the local SQLite database file for pnpm dev
.
# .env
DATABASE_URL=file:local.db
Apply initial local database migrations:
This will create the local.db
file (if it doesn't exist) and apply the schema defined in src/lib/server/db/schema.ts
.
pnpm run db:migrate
To run the application locally using the Vite development server (hot-reloading, uses local.db
SQLite file):
pnpm dev
Navigate to http://localhost:5173
(or the port specified in the output). Changes made to your Svelte components or server routes will reload automatically. Note that Cloudflare bindings (like D1) are not available in this mode.
To run the application locally using Miniflare, which simulates the Cloudflare Workers environment (including D1 bindings stored locally):
Ensure D1 is configured locally: You might need to run the D1 migrations locally first if you haven't configured your remote D1 DB yet (see Cloudflare Setup section). Wrangler often prompts or handles this. If you encounter D1 errors, try:
# Replace 'guestbook-db' if you used a different name in wrangler.jsonc
wrangler d1 migrations apply guestbook-db --local
Run the preview script:
This script first builds the SvelteKit app (vite build
) and then starts the Wrangler development server (wrangler dev
).
pnpm preview
Navigate to http://localhost:8787
(or the port specified in the output). This mode uses a local simulation of your D1 database defined in wrangler.jsonc
. Hot-reloading is not available; you need to stop and restart pnpm preview
to see changes.
Migrations allow you to evolve your database schema over time.
Modify the schema: Edit the table definitions in src/lib/server/db/schema.ts
.
Generate migration files: Create SQL migration files based on schema changes. These files are stored in src/lib/server/db/migrations
.
pnpm run db:make-migrations
(Note: This uses drizzle-kit generate
. The blog post initially mentioned db:push
, but recommends generate
for better tracking.)
Apply migrations:
local.db
used by pnpm dev
):pnpm run db:migrate
pnpm preview
): Replace guestbook-db
with your D1 database name from wrangler.jsonc
.wrangler d1 migrations apply guestbook-db
guestbook-db
with your D1 database name.wrangler d1 migrations apply guestbook-db --remote
Before deploying, you need to create a D1 database on Cloudflare and configure Wrangler.
Create the D1 Database:
Choose a unique name for your database (e.g., guestbook-db
).
wrangler d1 create guestbook-db
Wrangler will output configuration details, including the database_id
.
Configure wrangler.jsonc
:
Add the d1_databases
binding information provided by the previous command to your wrangler.jsonc
file. Ensure the binding
name matches what's used in the code (DB
in this case) and add the migrations_dir
.
// wrangler.jsonc
{
// ... other config
"compatibility_flags": ["nodejs_compat"], // Ensure this is present
"d1_databases": [
{
"binding": "DB", // Important: Must match usage in hooks.server.ts (event.platform.env.DB)
"database_name": "guestbook-db", // Use the name you chose
"database_id": "YOUR_DATABASE_ID_HERE", // Paste the ID from 'wrangler d1 create' output
"migrations_dir": "./src/lib/server/db/migrations" // Points to your migration files
}
]
// ... other config (like assets)
}
Generate Cloudflare Types:
If you change bindings in wrangler.jsonc
, regenerate types for better TypeScript support:
pnpm run cf-typegen
This updates worker-configuration.d.ts
and ensures event.platform.env.DB
is correctly typed. Follow any instructions regarding @types/node
or tsconfig.json
cleanup if prompted.
Apply Migrations to Remote D1: Ensure your remote D1 database schema is up-to-date.
# Replace 'guestbook-db' with your D1 database name
wrangler d1 migrations apply guestbook-db --remote
Deploy the Worker: This script builds the application and deploys it to Cloudflare Workers using Wrangler.
pnpm run deploy
Wrangler will output the URL where your application is deployed (e.g., https://svelte-guestbook.<your-subdomain>.workers.dev
).
pnpm dev
: Run local dev server (Vite) with HMR. Uses local SQLite file (.env
).pnpm build
: Build the application for production.pnpm preview
: Build and run locally using Miniflare (simulates CF Workers). Uses local D1 preview.pnpm deploy
: Build and deploy to Cloudflare Workers. Uses remote D1.pnpm run db:make-migrations
: Generate SQL migration files from schema changes.pnpm run db:migrate
: Apply migrations to the local SQLite database (local.db
).pnpm run cf-typegen
: Generate TypeScript types based on wrangler.jsonc
.svelte.config.js
: SvelteKit configuration (uses @sveltejs/adapter-cloudflare
).vite.config.ts
: Vite configuration.wrangler.jsonc
: Cloudflare Wrangler configuration (Worker name, bindings, compatibility flags).drizzle.config.ts
: Drizzle Kit configuration (schema path, migrations output).tsconfig.json
: TypeScript configuration..env
: Environment variables for local development (e.g., DATABASE_URL
).src/app.d.ts
: App-level TypeScript declarations (including Locals
and Platform
).src/hooks.server.ts
: SvelteKit server hooks (used here for DB client initialization).src/lib/server/db/index.ts
: Database client initialization logic (handles D1 vs LibSQL).src/lib/server/db/schema.ts
: Drizzle schema definition.src/lib/server/db/migrations/
: Directory containing SQL migration files.
```