Skip to content

Monorepo: SvelteKit PWA Workspace Architecture

Section titled “Monorepo: SvelteKit PWA Workspace Architecture”

Date: 2026-03-06 Session: Extend monorepo with apps/ workspace for SvelteKit PWAs Status: ✅ Complete Commit: be9b5fe


Extended the existing Astro monorepo with a new apps/ pnpm workspace for SvelteKit PWAs. The first app (apps/sd-demo) is a working debt payoff calculator built with SvelteKit 2, Svelte 5 runes, Tailwind CSS, and vite-plugin-pwa. Design tokens are consumed directly via workspace link — no publishing friction.


  • Added apps/* to pnpm-workspace.yaml
  • Added eslint-plugin-svelte (flat/recommended) to root ESLint config
  • Added prettier-plugin-svelte to root Prettier config (formatting disabled in lint-staged — see Known Issues)
  • Scaffolded apps/sd-demo/ — complete SvelteKit PWA with working calculator page
  • Updated README.md and docs/ARCHITECTURE.md with new structure and SvelteKit decision rationale

Root config:

  • pnpm-workspace.yaml — added apps/*
  • eslint.config.mjs — added svelte plugin, added .svelte-kit/** and build/** to ignores
  • package.json — added eslint-plugin-svelte, prettier-plugin-svelte; added *.svelte lint-staged rule (ESLint only)
  • .prettierrc — added svelte plugin + parser override

Documentation:

  • README.md — updated Project Structure + Tech Stack
  • docs/ARCHITECTURE.md — updated structure diagram, workspace config, component philosophy, added “Why SvelteKit for Apps?” ADR block

New app:

  • apps/sd-demo/.gitignore
  • apps/sd-demo/package.json — SvelteKit 2 + vite-plugin-pwa + @smart-debt/design-tokens workspace dep
  • apps/sd-demo/svelte.config.js — adapter-static (pure static, Cloudflare Pages ready)
  • apps/sd-demo/vite.config.ts — sveltekit + VitePWA (autoUpdate, workbox)
  • apps/sd-demo/tailwind.config.js — CSS variable pattern (matches Template site)
  • apps/sd-demo/postcss.config.js
  • apps/sd-demo/tsconfig.json — extends .svelte-kit/tsconfig.json + skipLibCheck
  • apps/sd-demo/src/app.html — PWA HTML shell (manifest link, theme-color #005c2e)
  • apps/sd-demo/src/app.css — Tailwind directives + SmartDebt CSS custom properties (light/dark)
  • apps/sd-demo/src/app.d.ts — SvelteKit global types
  • apps/sd-demo/src/design-tokens.d.ts — ambient types for @smart-debt/design-tokens
  • apps/sd-demo/src/routes/+layout.svelte — imports app.css
  • apps/sd-demo/src/routes/+page.svelte — debt payoff calculator (Svelte 5 runes)
  • apps/sd-demo/static/favicon.svg — copied from Template SD brand
  • apps/sd-demo/static/manifest.json — PWA manifest (standalone display)

  • @smart-debt/design-tokens consumed via workspace:* — no npm publishing needed
  • One lockfile = consistent versions across all sites and apps
  • Brand assets (src/brand/) shared directly
  • Each app still deploys independently to its own Cloudflare Pages project
  • Astro optimized for content; SvelteKit for interactive PWAs with client-side routing
  • Svelte 5 runes compile to minimal vanilla JS
  • adapter-static → pure static output, CDN-ready, no server needed
  • vite-plugin-pwa integrates natively with SvelteKit’s Vite pipeline
  • Apps deploy to *.pages.dev subdomains
  • Astro marketing pages embed via <iframe src="https://sd-demo.pages.dev">
  • Iframes = isolated, sandboxed, portable to third-party sites

CheckResult
pnpm build (sd-demo)✅ Builds to build/ with service worker + workbox
pnpm lint (monorepo root)✅ 0 errors (7 pre-existing warnings only)
pnpm check (sd-demo svelte-check)✅ 0 errors, 0 warnings
pnpm test (design-tokens unit)✅ 26/26 pass
Pre-commit hook✅ Passes (lint-staged ESLint on .svelte files)

prettier-plugin-svelte incompatible with Svelte 5 syntax

Section titled “prettier-plugin-svelte incompatible with Svelte 5 syntax”
  • Error: TypeError: getVisitorKeys is not a function or its return value is not iterable
  • Cause: prettier-plugin-svelte v3.5.1 (latest) doesn’t handle Svelte 5 rune syntax ($state, $derived, $props) in Prettier v3.8
  • Mitigation: .svelte files excluded from prettier formatting in lint-staged (ESLint-only) — same pattern as .astro files in this repo
  • Resolution: Watch for prettier-plugin-svelte v4 which will support Svelte 5

  1. Deploy sd-demo — create Cloudflare Pages project, run pnpm build + wrangler deploy
  2. Embed teaser — add iframe embed on Template site (components showcase or dedicated page)
  3. Add more routes — avalanche vs. snowball comparison, amortization schedule table
  4. Color generation — optionally wire up pnpm colors:sd equivalent for the app
  5. CI — add sd-demo to GitHub Actions matrix when ready for continuous deployment

Terminal window
# Development
pnpm --filter @smart-debt/sd-demo dev # Start dev server
# Build
pnpm --filter @smart-debt/sd-demo build # Static build → apps/sd-demo/build/
# Type check
pnpm --filter @smart-debt/sd-demo check # svelte-check
# Lint (from monorepo root)
pnpm lint # ESLint across all sites + apps