v2 · Cohort opens 2026·06 180 seats v1 owners → v2 free
v2 · A course in twenty-three modules

Ship production SvelteKit.
Not toy apps.

Second edition. An opinionated course on building a multi-tenant SaaS in SvelteKit 2, shipping it on a VPS you actually run, and not lying to yourself about any of it. Svelte 5, Drizzle, Better Auth, Stripe Connect.

Format
Cohort + self-paced · video + written
Length
23 modules · ~110 lessons · video + written
Stack
Svelte 5 · SvelteKit 2 · Postgres
App
Multi-tenant invoicing SaaS

Most SvelteKit material stops at the demo. You finish the tutorial, you build the todo app, and the moment you try to ship something with paying users you are alone with decisions no blog post covers.

This course is the opposite of that. It comes out of running real SvelteKit apps in production, at one hundred and eight hundred thousand users a month, and writing down the decisions that mattered. The ones nobody told you about. The ones you only learned by losing a weekend.

No filler. No ten-minute lessons that say what the docs already say. Every module earns its place by saving you a problem that is going to find you anyway.

You'll be able to do four things you can't do today

  1. 01

    Ship a multi-tenant SaaS, not a tutorial app

    You'll build a freelancer invoicing platform from empty repo to paying users. Workspaces, recurring invoices, PDFs, Stripe Connect payouts. The kind of app you can actually put a price tag on.

  2. 02

    Own the data layer with Drizzle and Postgres

    Drizzle schemas that still make sense to you in six months. Migrations you can run in production without flinching. Multi-tenant scoping that doesn't leak rows between workspaces because someone forgot a where clause.

  3. 03

    Wire up auth, payments, payouts, and email properly

    Better Auth wired the way you'd actually want it. Stripe Connect for payouts to seller accounts. Webhooks that handle retries the way Stripe expects. Email that lands in inboxes, jobs that run on time.

  4. 04

    Operate it on a VPS — not just deploy it

    Provision an Ubuntu box, run the app behind Caddy, deploy without downtime. Backups you've actually restored from at least once. Logs and PostHog events wired up so you find out about a bug before your users do.

The exact tools, with reasons

No mystery dependencies. Every choice below is the one I'd make today if I were starting a new SvelteKit SaaS from scratch.

  1. 01 Svelte 5 Component runtime · runes Reactivity that survives an app, not just a demo
  2. 02 SvelteKit 2 Application framework One model that covers server, browser, and edge
  3. 03 TypeScript The language No mystery types six months from now
  4. 04 PostgreSQL Primary database Self-hosted on a VPS. Alternatives covered
  5. 05 Drizzle ORM Schema · queries · migrations SQL you can read, types you can trust
  6. 06 Better Auth Authentication Email + OAuth, sessions over JWTs
  7. 07 Tailwind 4 Styles No bespoke design system to maintain
  8. 08 shadcn-svelte UI primitives Copy-in components you actually own
  9. 09 Valibot Validation Schemas shared across server and client
  10. 10 pg-boss Background jobs A queue that lives in your database
  11. 11 Resend Transactional email Templates as components, not strings
  12. 12 Stripe Connect Payments and payouts Payment intents on connected accounts
  13. 13 Docker · Caddy · VPS Deployment Ubuntu, docker-compose, Lets Encrypt

Twenty-three modules, roughly one hundred and ten lessons, every one of them earning its place

Listed below in full. Video-first per lesson, with a condensed written companion per module so you can revisit without scrubbing video. If a lesson doesn't save you a problem you'd otherwise hit, it doesn't exist in the course.

  1. 00 4 lessons

    Course intro

    Quick orientation. What we'll build, what you should already know, where the repo lives, how the lesson companions work.

    • 0.1 What we will build, end to end
    • 0.2 Prerequisites and stance
    • 0.3 The repo, branches, and lesson companions
    • 0.4 How this course is different
  2. 01 5 lessons

    Svelte 5 fundamentals

    Runes from first principles. Snippets and {@render}. Attachments. The .svelte.ts files and class-based state that quietly change how you structure a Svelte app.

    • 1.1 $state, $derived, $effect — the core three
    • 1.2 $derived.by, $effect.pre, $state.raw, $state.snapshot
    • 1.3 Snippets, {@render}, and replacing slots
    • 1.4 {@attach} and events as attributes
    • 1.5 .svelte.ts files, classes as state, $props.id()
  3. 02 5 lessons

    SvelteKit 2 fundamentals

    Routing, layouts, loads, hooks. The boundary between server and browser code. The mental model you need before you commit to a project structure.

    • 2.1 Routing, layouts, and route groups
    • 2.2 Loads — universal vs server, params, parent()
    • 2.3 Parallel loads, invalidation, streaming promises
    • 2.4 +server.ts, hooks, and request handlers
    • 2.5 $lib/server, $env/static vs $env/dynamic
  4. 03 4 lessons

    Project bootstrap

    A project skeleton that scales. TypeScript, Tailwind 4, shadcn-svelte. The naming and folder conventions that keep a two-hundred-route app navigable a year in.

    • 3.1 TypeScript config that scales
    • 3.2 Tailwind 4 + shadcn-svelte setup
    • 3.3 ESLint, Prettier, and conventions that compound
    • 3.4 Base layout, navigation, page options
  5. 04 5 lessons

    Database — Postgres + Drizzle

    Schemas you can read out loud. Migrations you can run in production without crossing your fingers. A self-hosted Postgres on a VPS that you actually control, with backups that work.

    • 4.1 Schema design — cuid2, timestamps, relations
    • 4.2 Self-hosted Postgres on a VPS — docker-compose and backups
    • 4.3 Migrations: generate, review, ship, recover
    • 4.4 Per-table organization and transactions
    • 4.5 Sidebar — Supabase, Neon, PlanetScale tradeoffs
  6. 05 5 lessons

    Forms & data mutations

    Form actions, use:enhance, and fail() as the foundation. Then remote functions (form, command, query, prerender) and when each one replaces the older pattern.

    • 5.1 Form actions, use:enhance, fail() — the foundation
    • 5.2 Remote functions — form, command, query, prerender
    • 5.3 When remote functions replace older patterns
    • 5.4 Valibot schemas shared across client and server
    • 5.5 Optimistic UI via derived overriding
  7. 06 5 lessons

    Authentication — Better Auth

    Email and password done correctly. OAuth without a third-party SDK. Sessions in cookies. Auth checks placed where they will actually run, not where they get silently skipped on a client-side navigation.

    • 6.1 Better Auth setup — sessions, hooks, getRequestEvent()
    • 6.2 Email + password — signup, verify, reset
    • 6.3 OAuth — Google and GitHub, properly
    • 6.4 Where auth checks live (and why not in layouts)
    • 6.5 Account settings, email change, deletion
  8. 07 5 lessons

    Multi-tenant data model

    Workspaces, membership, invitations. Scoping patterns that hold up under refactor. Defense in depth, so a missed where clause never leaks rows between tenants.

    • 7.1 Workspaces, membership, invitations
    • 7.2 Workspace switcher and state
    • 7.3 Scoping every query — patterns that hold up
    • 7.4 Row-level safety as defense in depth
    • 7.5 Inviting, rotating, and revoking access
  9. 08 5 lessons

    Building the app — clients & invoices

    The product itself. List views with search and pagination. Detail panes via shallow routing. A streaming dashboard. Totals that survive currencies, tax, and rounding.

    • 8.1 Modeling clients, invoices, line items, statuses
    • 8.2 List views — search, filter, pagination
    • 8.3 Detail panes via shallow routing
    • 8.4 A dashboard with streaming loads
    • 8.5 Computing totals — currency, tax, rounding
  10. 09 4 lessons

    PDF generation

    Server-side PDF generation that renders consistently. For the invoice itself, for receipts, for anything else that has to leave the system as a document.

    • 9.1 Server-side PDF generation strategy
    • 9.2 Templating an invoice PDF
    • 9.3 Storage and download endpoints
    • 9.4 Consistent rendering across locales
  11. 10 4 lessons

    File uploads

    Local dev to S3-compatible storage. Signed URLs. Image resizing on upload. Attaching files to records without leaking access.

    • 10.1 Local dev — filesystem and signed URLs
    • 10.2 S3-compatible storage — R2, Tigris, MinIO
    • 10.3 Image resizing on upload
    • 10.4 Attaching files to records
  12. 11 4 lessons

    Email — Resend

    Transactional email treated as a subsystem of its own. Templates as components. Deliverability that lands inboxes. The unsubscribe flow you need before launch day.

    • 11.1 Templates and the dev preview
    • 11.2 Transactional sends — invoices, receipts, reminders
    • 11.3 Deliverability — DKIM, SPF, DMARC, warm-up
    • 11.4 Unsubscribe and compliance
  13. 12 5 lessons

    Background jobs — pg-boss

    A queue that lives in your Postgres. Recurring invoices, payment reminders, retries, dead-letter handling. A basic ops dashboard so you can sleep at night.

    • 12.1 Why a queue lives in your database
    • 12.2 Recurring invoices — scheduling and drift
    • 12.3 Payment reminders and digest emails
    • 12.4 Retries and dead-letter handling
    • 12.5 A basic ops dashboard for jobs
  14. 13 5 lessons

    Stripe Connect

    Onboarding connected accounts. Payment intents. Payment links per invoice. Webhooks that survive Stripe's retry policy. A test-mode workflow you can trust before you flip to live.

    • 13.1 Onboarding — Standard vs Express
    • 13.2 Payment intents on connected accounts
    • 13.3 Payment links per invoice
    • 13.4 Webhooks — signature verification and idempotency
    • 13.5 Refunds, payouts, and the test-mode workflow
  15. 14 4 lessons

    Real-time

    SSE for invoice status. Reconciling SSE state with SvelteKit's invalidate(). A clear-eyed look at when WebSockets and Durable Objects start paying off.

    • 14.1 SSE for invoice status — sent, viewed, paid
    • 14.2 Reconciling SSE with invalidate()
    • 14.3 When to reach for WebSockets
    • 14.4 When to reach for Durable Objects
  16. 15 5 lessons

    Admin dashboard

    A separate /admin route group with role gating. The metrics that matter (MRR, GMV, connected-account health). The manual interventions every product eventually needs.

    • 15.1 The /admin route group and role gating
    • 15.2 MRR, GMV, connected-account health
    • 15.3 User search and impersonation
    • 15.4 Manual interventions — refunds, comping plans
    • 15.5 Audit log — what to log and how
  17. 16 4 lessons

    Errors, loading, edge cases

    error() vs handleError(). +error.svelte boundaries that help instead of hiding the bug. Transport hooks for Date and BigInt. The Stripe webhook failure modes that will eventually find you.

    • 16.1 error() vs handleError() — the right tool
    • 16.2 +error.svelte boundaries that help
    • 16.3 Transport hooks — Date, BigInt, custom types
    • 16.4 Stripe webhook failure modes you must handle
  18. 17 4 lessons

    Testing

    Unit tests where they pay, skipped where they don't. Integration tests against a real Postgres. Playwright running through Stripe test mode. Tests that don't break the moment you refactor.

    • 17.1 Vitest unit tests that pay
    • 17.2 Integration tests against a real Postgres
    • 17.3 Playwright — auth flows and Stripe test mode
    • 17.4 Test factories and CI
  19. 18 4 lessons

    Performance & SEO

    Image optimization. Prerendering marketing pages. JSON-LD, sitemaps, meta tags. A Lighthouse pass that doesn't lie to you.

    • 18.1 Image optimization in SvelteKit
    • 18.2 Prerendering marketing pages
    • 18.3 JSON-LD, sitemap, meta — the works
    • 18.4 The Lighthouse pass that matters
  20. 19 5 lessons

    Observability

    Structured logs you can grep. PostHog wired up for the events that matter (HTTP requests, user events, errors). Typed event wrappers instead of ad-hoc capture calls. Request IDs that correlate browser to server.

    • 19.1 Structured logs — what to log and what to skip
    • 19.2 PostHog on the client — init, identify, reverse-proxy
    • 19.3 Server-side PostHog — typed event wrappers in hooks
    • 19.4 Errors via PostHog captureException
    • 19.5 Request IDs and correlating browser → server
  21. 20 6 lessons

    Deployment — VPS

    Ubuntu provisioning, Docker, Caddy with Let's Encrypt. Zero-downtime deploys. Migrations that run on deploy. Healthchecks. A backup-and-restore drill you've already done once, on a Sunday, before you needed it.

    • 20.1 Provisioning Ubuntu — SSH and firewall hardening
    • 20.2 Docker + docker-compose for app and Postgres
    • 20.3 Caddy with Lets Encrypt
    • 20.4 Migrations on deploy and zero-downtime
    • 20.5 Healthchecks and rolling back fast
    • 20.6 Sidebar — same app on Vercel and Cloudflare
  22. 21 9 lessons

    Working with coding agents

    Setting your SvelteKit project up so coding agents are productive on it instead of producing slop you have to clean up. AGENTS.md and CLAUDE.md. The framework gotchas to encode. Post-edit contracts the agent has to run. Knowing when an agent earns its keep, and when it costs more than it saves.

    • 21.1 The case for agent-native SvelteKit development
    • 21.2 AGENTS.md and CLAUDE.md — what to write, what to leave out
    • 21.3 Encoding the gotchas the framework won't catch
    • 21.4 Per-folder AGENTS.md for narrowing context
    • 21.5 Pointing agents at the right docs (Svelte and SvelteKit llms.txt)
    • 21.6 Post-edit contracts — format, lint, check as commands the agent runs
    • 21.7 Plan mode and reviewing approach before code lands
    • 21.8 Subagents and skills for repeatable workflows
    • 21.9 Knowing when to skip the agent
  23. 22 5 lessons

    Appendices

    The migrations and tradeoffs you'll eventually face. Svelte 4 to 5. Lucia to Better Auth. Prisma to Drizzle. When Postgres should become D1 or Turso.

    • 22.1 Svelte 4 → 5 migration
    • 22.2 Lucia → Better Auth migration
    • 22.3 Prisma → Drizzle migration
    • 22.4 When Postgres should become D1 or Turso
    • 22.5 BullMQ vs pg-boss revisited

A freelancer invoicing SaaS, end to end

One app, threaded through every module, finished by the end. Not three half-built demos. By module twenty-one it's multi-tenant, takes payments via Stripe Connect, chases late payers automatically, and runs on a VPS you provisioned by hand.

Project Invoyce Svelte 5 · SvelteKit 2 · Postgres · Stripe Connect
  1. 01 Workspaces with membership and invitations
  2. 02 Clients, invoices, line items, recurring invoices
  3. 03 Server-side PDF generation and download endpoints
  4. 04 Stripe Connect onboarding and payouts to seller accounts
  5. 05 Webhooks with signature verification and idempotency
  6. 06 Real-time invoice status (sent · viewed · paid) over SSE
  7. 07 Background jobs for reminders and recurring billing
  8. 08 Admin dashboard — MRR, GMV, audit log, manual interventions
  9. 09 Self-hosted on a VPS — Docker, Caddy, zero-downtime deploys

Sègbédji Justin Ahinon

Senior software engineer · founder of Okupter · WordPress Core alum · running production SvelteKit since 2022

Six years shipping web applications that real people pay for or depend on. SvelteKit specifically since 2022. In that time I've led React and Next.js → SvelteKit migrations on production codebases, and I shipped the MVP for an education platform that now serves one hundred thousand developers a month.

Most of what I build now is in SvelteKit. DishCost, a recipe-costing SaaS for independent restaurants. WhatIsThatMovie, which finds films from vague descriptions, around thirty thousand visitors a month. Its sibling WhatIsThatBook, around four thousand a month and up one hundred and forty percent month over month. A handful of smaller things, including an open-source pg-boss wrapper for SvelteKit, because nothing decent existed for the queue patterns we cover in module 12.

Before that, two years as a full-time WordPress Core contributor sponsored by Yoast. I managed the Performance team, led the Playwright migration of the e2e suite, and coordinated documentation for two major releases. That's the work that taught me what production really means.

The plan for this course is to put down everything I'd tell a friend who came to me on day one of a new SvelteKit app and said: do not let me waste a year.

Shipped
Updraft (100k MAU) · ApeSpace (800k MAU) · DishCost · WhatIsThatMovie (30k MAU) · WhatIsThatBook
Open source
pg-boss for SvelteKit · KitForStartups · WordPress Core contributor (Yoast-sponsored) · Gutenberg documentation system
Past
Fabric Blockchain Labs · Cyfrin · WebDevStudios · Awesome Motive · Yoast

One tier. Everything included. No upsells.

v1 → v2
Already own v1? Your access is being upgraded to v2 at no cost. Watch your inbox around launch. If the email doesn't show up, write in and we'll sort it the same day.
Full Stack SvelteKit · v2 · Cohort I
$119 $89 First 20 seats · USD · paid once
  • All twenty-three modules · roughly one hundred and ten lessons · video + written companion
  • Source code for every project, every commit, every branch
  • Cohort access (twelve weeks of office hours and a private channel)
  • Self-paced access after the cohort closes. Same material, same channel.
  • Lifetime updates. When the framework moves, the course moves with it.
  • Free upgrade to all future major versions, the same way v1 owners got v2
  • Fourteen-day no-questions refund

Need a team license, an invoice, or a country-specific PPP discount? Reach out before checkout.

Things people ask before reserving a seat

Q.01 I bought v1. What do I do?
Nothing. Your access is being upgraded to v2 automatically and you'll get an email with the new course link as soon as the cohort opens. If it doesn't show up by launch day, write in and we'll sort it the same day.
Q.02 Who is this for?
Developers comfortable in JavaScript or TypeScript who want to ship a real, paying SvelteKit app (auth, billing, payouts, deploys) and stop guessing at every architectural decision. If you've built side projects but never one that survived its first hundred users, you are the audience.
Q.03 Do I need to know Svelte 5 already?
No. Module 1 grounds Svelte 5 from a real-app perspective (runes, snippets, attachments) and module 2 does the same for SvelteKit 2. If you've used React, Vue, or Solid in production, you'll keep up.
Q.04 What about the framework changing?
The course is built against Svelte 5 and SvelteKit 2 and tracks the framework as it evolves. When something material shifts (a new adapter, a runtime change, a Svelte version), modules are revised and existing students get the update at no cost.
Q.05 Is there a cohort, or self-paced?
Both. The first cohort runs over twelve weeks with weekly office hours and a private channel. After it closes the same material is available self-paced, and the channel stays open.
Q.06 What if I need a refund?
Fourteen days, no questions. After that, the material is yours.
Q.07 Do you offer a team license?
Yes. Five and ten-seat tiers with invoice billing and a private cohort channel for your team. Reach out before checkout and we'll set it up.

If you're tired of tutorials that stop right before the part that matters, this is the course I wish someone had handed me.