# VerdantStack — Full Documentation for AI Agents > Three SvelteKit starters for B2B SaaS over one shared service layer: organizations → members → invites → role-based access → seat billing → append-only audit log. Every kit ships 325–390 automated tests and a live demo of the real thing. Each kit also ships an AGENTS.md and a generated TypeDoc API reference, and this site publishes llms.txt and llms-full.txt. ## About ### Release history (maintenance evidence) - [Changelog](https://verdantstack.dev/changelog/) — every dated release across all three kits, newest first, grouped by track. - 36 dated releases and 153 individual changes between 2026-08-26 and 2026-10-04 (40 days), spanning 3 kits. - Latest: Multi-tenant v0.2.14 (2026-10-04), SvelteKit + Postgres v0.1.13 (2026-10-04), SvelteKit + Supabase v0.3.4 (2026-10-04). - The page is **generated at build time** by parsing each kit's `CHANGELOG.md` in the repository, and `ops/scripts/check-changelog-sync.mjs` fails the build if the rendered totals disagree with those files. A release cannot be advertised without a changelog entry behind it. - Why this is published: the most common free alternative, CMSaasStarter, has never published a tagged release, and its most recent commit is 2026-03-21 (https://github.com/scosman/CMSaasStarter/commits/main). Whether that remains true is the reader's to check — the point is that a dated changelog makes the question answerable without asking the vendor. VerdantStack builds SvelteKit starters for B2B SaaS. All three sit on one service layer — organizations, members, invites, role-based access, seat billing, an append-only audit log — and differ in the database they run on and the auth they use. Each kit also ships an AGENTS.md and a generated TypeDoc API reference, so tools like Claude Code, Cursor, and Copilot read the real surface instead of guessing. Those context files are included because they are cheap and useful, not because they are unusual: Svelte's own CLI (`npx sv add ai-tools`) scaffolds a framework-level AGENTS.md into any SvelteKit project, and ours is the product-specific layer on top of it. The unglamorous core of a SaaS product — tenancy, roles, billing, audit — is the layer every product needs and the one most worth not rebuilding from scratch. An agent can write a first draft of it in an afternoon, but it cannot tell you whether the tenant scoping, the seat accounting, or the audit trail is actually correct. Our starters ship that layer wired and covered, so your time goes to what makes your product different. ## Products ### All products (index) URL: https://verdantstack.dev/products/ Hub page listing every VerdantStack starter — product pages, documentation, GitHub repositories, and buy links — maintained from the site's product config. ### Multi-tenant SvelteKit Starter URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/ Repository: https://github.com/verdantstack/multi-tenant-sveltekit-starter Status: v0.2.14 — 357 automated tests, clean-room install verified License: source-available to buyers (EULA); not open source A production-shaped B2B SaaS foundation for SvelteKit with multi-tenancy wired end-to-end. **Features:** - Organizations & membership — create, join, leave; single-use invite links with expiry and atomic claim; ownership transfer - Role-based access control — three built-in roles (owner > admin > member) with strict hierarchy enforced server-side on every request - Seat-based billing seam — BillingAdapter interface with seat limits enforced at join-time; checkout through a merchant of record - Append-only audit log — who did what, queryable, export-ready; no update or delete path exists - Auth that survives review — scrypt-hashed passwords, hashed revocable database sessions - Rate limiting — sliding-window failed-attempt limiter with pre-hash blocking **Tech Stack:** - Runtime: SvelteKit (Svelte 5) - Database: SQLite via better-sqlite3 + Drizzle ORM - Auth: scrypt password hashing, SHA-256 session tokens - Testing: Vitest (357 tests against :memory: databases) - Release gate: every published kit is unzipped into an empty directory, installed with no cache, and its test suite run before release - Deployment: Any Node.js host (adapter-auto) **Quick Start (buyers receive the full source at purchase):** ```bash # The kit source ships privately to buyers — the public repo is the # proof layer (docs, features, screenshots). Buy the kit to get the code: # https://verdantstack.dev/products/multi-tenant-sveltekit-starter/ # Buyers then run: npm install npm run dev # http://localhost:5173 npm test # vitest suite (357 tests) ``` **Environment Variables:** | Variable | Default | Purpose | |----------|---------|---------| | DATA_DIR | ./data | Where the SQLite file lives | | MOCK_PLAN_SEATS | 3 | Seat limit while on MockBilling | | AUTH_FAILED_ATTEMPTS | 5 | Failed attempts allowed per window | | AUTH_WINDOW_MS | 900000 | Sliding window for failed auth attempts | **Pricing:** - Early-bird: $79 - Standard: $129 - One license, one developer, lifetime updates + lifetime standard support included - Lifetime use of the version you downloaded - Refund within 30 days, no hassle --- ### SvelteKit + Supabase Starter URL: https://verdantstack.dev/products/sveltekit-supabase-starter/ Repository: https://github.com/verdantstack/sveltekit-supabase-starter Status: v0.3.4 — 390 automated tests, clean-room install verified License: source-available to buyers (EULA); not open source A SvelteKit starter with Supabase: organizations, invites, roles, seat billing, audit log. Same features as the SQLite starter, running on Supabase for auth, database, and realtime. **Features:** - Organizations & membership — create, join, leave; invite links with expiry; ownership transfer - RBAC via Supabase RLS — three built-in roles (owner > admin > member) enforced server-side via Row Level Security - Seat-based billing — pluggable BillingAdapter for merchant-of-record checkout - Append-only audit log — who did what, queryable, export-ready - Supabase Auth — email+password, magic links, OAuth providers - PostgreSQL via Supabase — managed PostgreSQL with connection pooling, backups, scaling **Tech Stack:** - Runtime: SvelteKit (Svelte 5) - Database: PostgreSQL via Supabase (with RLS) - Auth: Supabase Auth - Testing: Vitest (390 tests against an in-memory fake Supabase client) - Deployment: Any Node.js host **Pricing:** - Early-bird: $99 - Standard: $179 - One license, one developer, lifetime updates + lifetime standard support included --- ### SvelteKit + Postgres Starter URL: https://verdantstack.dev/products/sveltekit-postgres-starter/ Status: v0.1.13 — 325 automated tests against a real Postgres test database, clean-room install verified License: source-available to buyers (EULA); not open source A multi-tenant SvelteKit starter on real Postgres: organizations, invites, roles, seat billing, audit log — with Drizzle ORM + postgres.js, opt-in Row-Level Security, connection pooling, and no provider lock-in. **Features:** - Organizations & membership — create, join, leave; single-use invite links with expiry and atomic claim; ownership transfer - Role-based access control — three built-in roles (owner > admin > member) with strict hierarchy enforced server-side on every request - Seat-based billing — pluggable BillingAdapter for merchant-of-record checkout, enforced at invite acceptance - Append-only audit log — who did what, queryable, export-ready; no update or delete path exists - Auth — scrypt-hashed passwords, hashed revocable database sessions - Rate limiting — sliding-window failed-attempt limiter with pre-hash blocking - Postgres + Drizzle ORM — uuid PKs, bigint-ms timestamps, schema-first migrations via drizzle-kit - Opt-in Row-Level Security — fail-closed RLS policies with a per-request identity pattern (defense-in-depth) - Connection pooling — postgres.js pool config + PgBouncer/Supavisor/Neon guidance - Documented add-yourself upgrades — read replicas, JSONB metadata, full-text search (tsvector + GIN) **Tech Stack:** - Runtime: SvelteKit (Svelte 5) - Database: PostgreSQL (any provider — Neon, Railway, Supabase-direct, Fly.io, self-hosted) via postgres.js + Drizzle ORM - Auth: scrypt password hashing, SHA-256 session tokens - Testing: Vitest (325 tests against a real Postgres test database; docker-compose provides dev + test Postgres 16) - Deployment: Any SvelteKit adapter + any Postgres **Environment Variables:** | Variable | Default | Purpose | |----------|---------|---------| | DATABASE_URL | (required) | Postgres connection string (app) | | TEST_DATABASE_URL | (required for tests) | Postgres connection string (test DB) | | PG_MAX_CONNECTIONS | 20 | Connection pool size (postgres.js) | | PG_IDLE_TIMEOUT | 20 | Idle-connection close timeout (s) | | PG_CONNECT_TIMEOUT | 10 | Connection timeout (s) | | MOCK_PLAN_SEATS | 3 | Seat limit while on MockBilling | | AUTH_FAILED_ATTEMPTS | 5 | Failed attempts allowed per window | | AUTH_WINDOW_MS | 900000 | Sliding window for failed auth attempts | **Pricing:** - Early-bird: $79 - Standard: $129 - One license, one developer, lifetime updates + lifetime standard support included --- ## Live Demos All three products have a free, clickable, live demo of the real shipped kit (no signup to view; demo credentials are printed on each landing page). These are open demo databases, reset daily. ### Multi-tenant SvelteKit Starter — Live Demo URL: https://multi-tenant-starter.verdantstack-site.pages.dev/ The real Multi-tenant SvelteKit Starter kit running on Cloudflare Pages + D1, seeded with the Northwind Labs organization: owner `dana@northwind.example` / `Dana-demo-2026` and member `riley@northwind.example` / `Riley-demo-2026`. Explore orgs, invitations, RBAC, seat billing, and the append-only audit log live. ### SvelteKit + Supabase Starter — Live Demo URL: https://supabase-starter.verdantstack-site.pages.dev/ The real SvelteKit + Supabase Starter kit running on Cloudflare Pages + Supabase Postgres (Row Level Security enabled), seeded with the same Northwind Labs demo data (owner `dana@northwind.example` / `Dana-demo-2026`, member `riley@northwind.example` / `Riley-demo-2026`). ### SvelteKit + Postgres Starter — Live Demo URL: https://postgres-starter.verdantstack-site.pages.dev/ The real SvelteKit + Postgres Starter kit running on Cloudflare Pages + any-Postgres (postgres.js + Drizzle ORM), seeded with the same Northwind Labs demo data (owner `dana@northwind.example` / `Dana-demo-2026`, member `riley@northwind.example` / `Riley-demo-2026`). --- ## Comparisons & Guides ### Documentation Index URL: https://verdantstack.dev/docs/ Hub page listing product documentation, shared guides, comparisons, and the license agreement. ### SvelteKit vs Next.js for SaaS URL: https://verdantstack.dev/comparison/sveltekit-vs-nextjs-saas/ Honest comparison of SvelteKit and Next.js for building SaaS applications: performance, pricing, developer experience, and when to choose each framework. **Verdict:** SvelteKit wins for solo developers and small teams building B2B SaaS. Next.js wins for enterprise ecosystems. ### Multi-Tenant Starter Kit Checklist URL: https://verdantstack.dev/comparison/multi-tenant-starter-checklist/ The 5 essential features every multi-tenant starter kit must have: 1. Organization isolation (database-level) 2. Role-based access control (server-side) 3. Invitation system (email-based) 4. Billing integration (Stripe or MoR) 5. Audit logging (append-only) ### Best SvelteKit SaaS Starters in 2026 URL: https://verdantstack.dev/bestof/sveltekit-saas-starters-2026/ Comparison of the top SvelteKit starter kits for building multi-tenant B2B SaaS applications. Covers features, pricing, and best-fit scenarios. ### VerdantStack vs CMSaasStarter URL: https://verdantstack.dev/comparison/sveltekit-starter-vs-cmsaasstarter/ Feature-by-feature comparison of VerdantStack Multi-tenant SvelteKit Starter vs CMSaasStarter (a free open-source Supabase starter). Covers auth, tenancy, RBAC, billing, audit, database, and deployment. ### SvelteKit + Postgres vs SvelteKit + Supabase URL: https://verdantstack.dev/comparison/sveltekit-postgres-vs-supabase/ Provider-neutral Postgres with Drizzle vs managed Supabase for a multi-tenant SvelteKit SaaS — auth, RLS, pooling, realtime, storage, cost, and lock-in tradeoffs. ### SvelteKit + Postgres vs Next.js + Prisma URL: https://verdantstack.dev/comparison/sveltekit-postgres-vs-nextjs-prisma/ Building a multi-tenant SaaS: SvelteKit server endpoints/form actions vs Next.js App Router, Drizzle vs Prisma, and Postgres hosting options. ### Drizzle ORM vs Prisma for SvelteKit SaaS URL: https://verdantstack.dev/comparison/drizzle-orm-vs-prisma-sveltekit/ SQL-first Drizzle vs Prisma's schema DSL for a SvelteKit SaaS — query API, migrations, type safety, overhead, and ecosystem. ### Supabase vs Drizzle URL: https://verdantstack.dev/comparison/supabase-vs-drizzle/ Supabase is a managed Postgres platform (database, auth, storage, realtime, RLS); Drizzle is a TypeScript ORM that connects to any Postgres, including Supabase's. They are not competitors — Supabase's own docs ship a Drizzle quickstart. Covers who hosts the database, who writes the queries, migrations, tenant isolation, connection handling, and which VerdantStack kit ships which. ### SQLite vs Postgres for a Multi-tenant SaaS URL: https://verdantstack.dev/comparison/sqlite-vs-postgres-multi-tenant-saas/ SQLite vs Postgres for a multi-tenant SvelteKit SaaS — concurrency model, connection handling, scaling ceiling, migrations, opt-in RLS, and the replica threshold at which you should switch. Written by a vendor that ships both kits, from the shipped source of each. ### The B2B SaaS data model: organizations, memberships, invites, and roles URL: https://verdantstack.dev/saas/b2b-organizations-memberships-data-model/ The six tables every B2B product needs, and the decisions inside them that production breaks. Why the role belongs to the membership rather than the user, why the join table should be constrained by a unique index and not by handler code, the four properties an invite must have (hashed token, expiry, single-use, atomic accept), why the audit log must outlive the rows it describes, and the operational cases — ownership transfer, the solo admin, invite rollback, seat changes — that no schema diagram shows. Framework-neutral; drawn from the schema and services our three kits actually ship. ### Multi-tenancy across stacks: how each framework isolates a tenant URL: https://verdantstack.dev/saas/multi-tenancy-across-stacks/ Where tenant isolation is actually enforced in Django, Rails, Laravel, Next.js, NestJS, Go, Phoenix and Postgres — and the specific code path in each that silently drops the tenant (background jobs, queued workers, unguarded routes). Seven of the eight are enforced by application code; Postgres row-level security is the one mechanism that is not a discipline, and it is stack-independent because the policy lives in the database. We ship SvelteKit and have not run the other seven, so this page names them and shows none of their code. ### SaaS starter kit evaluation: what free SvelteKit starters leave out URL: https://verdantstack.dev/docs/sveltekit-saas-boilerplate/ Compare free SvelteKit starters vs production-ready kits with RBAC, billing, and audit logging. What every B2B SaaS needs but few starters include. ### Multi-Tenant SvelteKit Template — Build B2B SaaS URL: https://verdantstack.dev/docs/multi-tenant-sveltekit-template/ How to implement organizations, role-based access control, seat billing, and audit logging in your SvelteKit B2B SaaS. Step-by-step with code examples. ### Make Your Codebase AI-Agent-Friendly URL: https://verdantstack.dev/docs/make-codebase-ai-agent-friendly/ AGENTS.md, llms.txt, and generated API references — the context files AI coding agents (Claude Code, Cursor, Copilot) need to work productively in your codebase, and how to add and maintain them so they cannot rot. ### How to Build Multi-Tenant SaaS with SvelteKit URL: https://verdantstack.dev/docs/how-to-build-multi-tenant-saas-sveltekit/ Step-by-step guide covering project setup, database schema, authentication, multi-tenancy, and role-based access control in SvelteKit. --- ## Documentation ### Multi-tenancy in SvelteKit, at the application layer URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/docs/sveltekit-multi-tenant-auth/ Most multi-tenancy advice starts with database features you may not have (RLS, schema-per-tenant) or vendor products you may not want. For small B2B SaaS there's a third path: tenancy as plain application logic, enforced where your queries are built. **Key patterns:** - One shared schema, every tenant-scoped row carries org_id, scope enforced where queries are constructed - Three tables carry most products: organizations, memberships, invites - Role lives on the membership, not the user — a person is an admin of this org, period - One membership per (org, user), enforced by unique index - Owner is a role, not a flag — ownership transfer becomes an ordinary role change **Production checklist:** 1. Every tenant-scoped row carries org_id with a composite unique index 2. Sessions store only sha256(token) — leaked sessions yield zero usable logins 3. Invite tokens: random 32 bytes, stored hashed, expiry timestamp, single-use enforced by conditional UPDATE 4. Permissions checked server-side on every load AND every action, from fresh DB state 5. Role hierarchy: actors act only strictly downward; nobody grants to their own rank 6. Last owner cannot leave or be removed 7. Audit row written inside the same service call as the mutation it records 8. Milliseconds everywhere, UTC only 9. Rate-limit failed auth attempts before launch ### RBAC: Role-Based Access Control URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/docs/sveltekit-rbac-role-hierarchy/ **Roles:** owner > admin > member (rank 2 > 1 > 0) **Capability matrix:** | Permission | owner | admin | member | |------------|:-----:|:-----:|:------:| | org.view | ✓ | ✓ | ✓ | | members.view | ✓ | ✓ | ✓ | | members.invite | ✓ | ✓ | — | | members.remove | ✓ | ✓* | — | | members.role.set | ✓ | ✓* | — | | invites.revoke | ✓ | ✓ | — | | audit.view | ✓ | ✓ | — | | billing.manage | ✓ | — | — | | ownership.transfer | ✓ | — | — | *subject to hierarchy rules **Hierarchy rules:** 1. Act downward only — mayActOn requires rank(actor) > rank(target) 2. Grant strictly below yourself — mayGrant requires rank(actor) > rank(granted) 3. No self-modification 4. Single-owner invariant — transferOwnership sets target→owner and actor→admin together ### Invite Link Flow URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/docs/sveltekit-invite-link-flow/ Single-use hashed invite tokens with expiry and atomic claim. **Key design:** - Link contains 32 bytes of entropy; database stores only SHA-256 - Shown once in UI, then unrecoverable - Expiry is a column compared against now(), not a cron job - Single-use enforced by conditional UPDATE: ```sql UPDATE invites SET accepted_at_ms = ? WHERE id = ? AND accepted_at_ms IS NULL AND revoked_at_ms IS NULL AND expires_at_ms > ? -- zero rows updated = someone else got there first ``` ### Seat Billing Adapter Pattern URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/docs/seat-billing-adapter-pattern/ Pluggable BillingAdapter interface for merchant-of-record checkout. **Interface:** ```typescript interface BillingAdapter { readonly name: string; getSubscriptionState(orgId: string): Promise; createCheckoutUrl(input: { orgId: string; seats: number }): Promise; } ``` **Enforcement:** Exactly one gate at invite acceptance (assertSeatAvailable). Inviting beyond seat count is allowed; limit surfaces at accept time. **Implementation:** MockBillingAdapter ships as default (every org "active", configurable seat limit). Real adapter maps MoR subscription webhooks to local rows. ### Append-Only Audit Log URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/docs/append-only-audit-log-design/ Audit trail design: append-only by construction, no update/delete path. **Design decisions:** - audit_log.orgId and actorUserId are plain text with index, NOT foreign keys — history must survive member removal - Metadata is a JSON string; writers decide what goes in - Raw invite token is never audited - Audit row written inside the same service call as the mutation ### Hashed Session Auth URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/docs/sveltekit-hashed-session-auth/ Database-backed sessions with hashed tokens for revocation. **Design:** - Token: 32 random bytes, hex - Cookie holds raw token (httpOnly, sameSite=lax, secure in prod) - DB stores only sha256(token) as PK - Expiry: fixed 30 days (sliding expiry deferred until real usage data) ### Rate Limiting Login URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/docs/sveltekit-rate-limiting-login/ Sliding-window failed-attempt rate limiter with pre-hash blocking. **Implementation:** - RateLimiter interface (swappable seam) - Sliding-window failed-attempt limiter - Only failures recorded; success calls reset() - Login action pre-checks key BEFORE any scrypt work - Key format: login:: - Env-tunable: AUTH_FAILED_ATTEMPTS (default 5), AUTH_WINDOW_MS (default 900000) **Scope honesty:** In-memory and per-process. For multi-instance, implement against shared store (Redis or SQL DB). ### SaaS Starter Evaluation Checklist URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/docs/saas-starter-evaluation-checklist/ Six-dimension evaluation framework for choosing a SaaS starter: 1. Multi-tenancy model (app-layer vs RLS vs IdP) 2. Auth & session design 3. Billing integration points 4. Audit & compliance readiness 5. Testing coverage & quality 6. Deployment & scaling path ### Sell Software Without Stripe URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/docs/sell-software-without-stripe-access/ Merchant-of-record options for developers in countries where Stripe isn't available. **Options:** - Lemon Squeezy: 5% + $0.50, handles VAT/sales tax, local bank payouts - Paddle: 5% + $0.50, individual sellers documented OK - Payhip: Free plan +5% fee - Gumroad: 10% + $0.50 (avoided pending local payout confirmation) ### Starter Checklist URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/docs/multi-tenant-starter-checklist/ Production readiness checklist for multi-tenant SaaS starters covering tenancy, auth, billing, audit, testing, and deployment. ### Drizzle ORM Migrations in SvelteKit URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/docs/drizzle-orm-migrations-sveltekit/ Schema-first database management with Drizzle Kit: migrations, type-safe queries, and SQLite-specific considerations. ### Multi-Tenant Database Design URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/docs/multi-tenant-database-design/ Shared-database tenant isolation patterns: tenant_id columns, membership scoping, and when to outgrow SQLite. ### SvelteKit Session Management URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/docs/sveltekit-session-management/ Server-side sessions with hashed tokens, httpOnly cookies, and database-backed revocation. ### SvelteKit Hooks & Middleware URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/docs/sveltekit-hooks-middleware/ Server-side request handling with hooks.server.ts: auth validation, session extraction, multi-tenant org resolution, and sequence composition. ### Testing SvelteKit with Vitest URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/docs/sveltekit-testing-vitest/ Unit tests, integration tests, and HTTP-level patterns from a 357-test suite covering auth, RBAC, invites, and rate limiting. ### SQLite for Production SaaS URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/docs/sqlite-production-saas/ When and how to use SQLite for multi-tenant applications: WAL mode, tenant isolation via org_id, connection handling, backups, and ceiling awareness. ### SvelteKit Environment Variables URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/docs/sveltekit-environment-variables/ Public vs private, static vs dynamic, .env files, Cloudflare Workers secrets, and startup validation patterns. ### SvelteKit Error Handling URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/docs/sveltekit-error-handling/ fail(), error(), redirect(), and the errorToFail mapper: typed error patterns for form actions with field-level validation. ### License Agreement URL: https://verdantstack.dev/docs/license/ End User License Agreement: single-seat license, unlimited projects, lifetime updates + lifetime standard support (async, 48h target), lifetime use of the purchased version, 30-day refund, and support via verdantstack@proton.me. ### SvelteKit + Supabase Starter — Documentation Product-specific guides for the SvelteKit + Supabase Starter (Supabase for auth, database, and realtime; PostgreSQL via Supabase with Row Level Security): ### SvelteKit + Supabase Starter — Architecture URL: https://verdantstack.dev/products/sveltekit-supabase-starter/docs/architecture/ Thin routes → framework-free services → rbac/billing seams → supabase/client.ts. Service-role vs user-scoped clients, RLS defense-in-depth, and environment variables. Service-only foundation: you wire the route layer. ### SvelteKit + Supabase Starter — RBAC & RLS URL: https://verdantstack.dev/products/sveltekit-supabase-starter/docs/rbac/ Three roles (owner > admin > member) enforced server-side at the application layer and again via Supabase Row Level Security. Capability matrix, hierarchy rules, and the single-owner invariant. ### SvelteKit + Supabase Starter — Seat Billing URL: https://verdantstack.dev/products/sveltekit-supabase-starter/docs/billing/ Pluggable BillingAdapter interface for merchant-of-record checkout, enforced at invite acceptance with seat_limit/no_plan/adapter_error codes. ### SvelteKit + Supabase Starter — Testing URL: https://verdantstack.dev/products/sveltekit-supabase-starter/docs/testing/ 16 Vitest suites (390 tests) run against an in-memory fake Supabase client — no database, no network. RLS policies verified with `supabase start`. ### SvelteKit + Supabase Starter — Versioning URL: https://verdantstack.dev/products/sveltekit-supabase-starter/docs/versioning/ Semantic Versioning and Keep a Changelog for the Supabase starter; version history and release process. ### SvelteKit + Postgres Starter — Documentation Product-specific guides for the SvelteKit + Postgres Starter (multi-tenancy, RBAC, billing, audit log on real Postgres with Drizzle ORM + postgres.js, opt-in Row-Level Security, no provider lock-in): ### SvelteKit + Postgres Starter — Multi-Tenant DB Design URL: https://verdantstack.dev/products/sveltekit-postgres-starter/docs/postgres-multi-tenant-drizzle-design/ Shared-database tenancy on Postgres with Drizzle ORM: org_id scoping, uuid PKs, bigint-ms timestamps, per-request service-layer isolation, and the membership model. ### SvelteKit + Postgres Starter — RLS Defense-in-Depth URL: https://verdantstack.dev/products/sveltekit-postgres-starter/docs/row-level-security-sveltekit-postgres/ Opt-in Row-Level Security for the Postgres starter: fail-closed FORCE RLS, the app.current_user_id GUC per request, helper functions, and per-table policies. ### SvelteKit + Postgres Starter — Connection Pooling URL: https://verdantstack.dev/products/sveltekit-postgres-starter/docs/sveltekit-postgres-connection-pooling/ postgres.js pool sizing (PG_MAX_CONNECTIONS, default 20), idle/connect timeouts, and when to add a transaction-mode pooler (PgBouncer/Supavisor/Neon). ### SvelteKit + Postgres Starter — Drizzle Migrations URL: https://verdantstack.dev/products/sveltekit-postgres-starter/docs/drizzle-postgres-migrations-sveltekit/ Schema-first Postgres migrations with drizzle-kit: edit schema.ts → generate → review → apply at boot or via `npm run db:migrate`. ### SvelteKit + Postgres Starter — Read Replicas URL: https://verdantstack.dev/products/sveltekit-postgres-starter/docs/postgres-read-replica-routing-sveltekit/ Write/read splitting with Drizzle: separate read/write handles, lag-tolerant read classification, and REPLICA_DATABASE_URL wiring. ### SvelteKit + Postgres Starter — Full-Text Search URL: https://verdantstack.dev/products/sveltekit-postgres-starter/docs/postgres-full-text-search-sveltekit/ Native Postgres tsvector + GIN full-text search over the audit log — no external search service required. ### SvelteKit + Postgres Starter — JSONB Metadata URL: https://verdantstack.dev/products/sveltekit-postgres-starter/docs/jsonb-metadata-saas-audit-logs/ Flexible audit-log metadata: the text-JSON default today, the documented jsonb upgrade path, and @> containment queries with GIN indexes. ### SvelteKit + Postgres Starter — Session Management URL: https://verdantstack.dev/products/sveltekit-postgres-starter/docs/postgres-session-management-sveltekit/ Hashed, DB-backed, revocable sessions with Postgres — 32-byte token, sha256 at rest, 30-day expiry, and revocation by row delete. --- ## Architecture **Layering:** ``` routes (+page.server.ts) thin: parse form → call service → fail/redirect │ services (orgs/members/invites) domain logic, pure functions, Db passed in │ rbac.ts / billing/ policy + payment seams │ db/index.ts better-sqlite3 + drizzle + migrations ``` **Rules:** 1. Routes never touch the database directly except to fetch read models via services 2. Services are framework-free — import nothing from @sveltejs/kit 3. Every mutating service call re-derives authority from arguments 4. Errors carry machine codes (AuthError, RbacError, InviteError, MemberError, OrgError, BillingError) **Database portability:** 1. Replace better-sqlite3 driver with e.g. drizzle-orm/node-postgres 2. Adjust column types (integer ms timestamps → timestamp), regenerate migrations 3. Services compile unchanged — they only use the shared Db type --- ## Repository Structure (public proof layer) The public GitHub repos are **proof-only**: they carry the README, docs, feature list and screenshots — **not** the kit's running source. The full `src/` ships privately to buyers. The structure below describes what buyers receive. ``` multi-tenant-sveltekit-starter/ (delivered to buyers at purchase) ├── src/ │ ├── lib/server/ │ │ ├── db/schema.ts # Drizzle schema │ │ ├── rbac.ts # Roles, permission matrix, hierarchy │ │ ├── auth.ts # scrypt hashing, session management │ │ ├── ratelimit.ts # RateLimiter interface + implementation │ │ ├── http.ts # Error-to-HTTP mapper │ │ └── services/ # Domain logic (orgs, members, invites) │ ├── routes/ # SvelteKit routes │ └── app.html # HTML shell ├── tests/ # Vitest suites ├── drizzle/ # SQL migrations ├── docs/ # Architecture, RBAC, billing, license ├── scripts/ # Kit scripts (migration runner) └── vitest.config.ts # Test runner + the ≥95% coverage gate ``` --- ## Contact - [Contact form](https://verdantstack.dev/contact/) — name, email, subject, message; stored in our own database, no third party - [Privacy](https://verdantstack.dev/privacy/) — what this site collects, column by column: no cookies, no third-party requests, no persistent identifier. Click events (`demo_click`, `buy_click`, `pricing_view`) are recorded first-party at `/api/event` with a salted, daily-rotating IP hash — the IP itself is never stored. Automated browsers are dropped; events are rate-limited per hashed IP. - Async support only: verdantstack@proton.me - Response target: 48 hours - GitHub org: https://github.com/verdantstack - Proof repositories (docs & features — buy the kit for the source): - [multi-tenant-sveltekit-starter](https://github.com/verdantstack/multi-tenant-sveltekit-starter) — public proof repo: docs & features, plus the generated API reference at `docs/api` - [sveltekit-supabase-starter](https://github.com/verdantstack/sveltekit-supabase-starter) — public proof repo: docs & features, plus the generated API reference at `docs/api` - [sveltekit-postgres-starter](https://github.com/verdantstack/sveltekit-postgres-starter) — public proof repo: docs & features, plus the generated API reference at `docs/api` - Product pages (buy links): https://verdantstack.dev/products/ ## CSRF protection in SvelteKit cookie auth URL: https://verdantstack.dev/products/multi-tenant-sveltekit-starter/docs/sveltekit-csrf-protection/ CSRF protection is four independent layers, not one: httpOnly, sameSite lax, SvelteKit's csrf.checkOrigin (on by default), and the design rule that GET never mutates. Two holes remain open even with all four: same-site subdomain attackers, because SameSite judges the site rather than the origin, and top-level GET navigation, which lax allows by design. Cookie options are single-sourced per starter and pinned by tests that also pin the known limits, so the documentation cannot drift into claiming coverage the code does not provide. The Supabase variant deliberately sets no maxAge because it holds a rotating Supabase refresh token. ## How to build SaaS features with AI coding agents URL: https://verdantstack.dev/docs/build-with-ai-agents/ How to drive VerdantStack starter kits with AI coding agents: which parts of a multi-tenant SvelteKit app an agent can safely generate, which parts carry the security decisions, and where the audit log and RBAC rules constrain the work. The three kits differ by data layer, so the agent-facing surface differs too. ## Using Claude Code with VerdantStack URL: https://verdantstack.dev/docs/claude-code-with-verdantstack/ How to use Claude Code with a VerdantStack starter kit: pointing the agent at the repo, the conventions the kits already encode so it does not reinvent auth or RBAC, and the checks worth running after every change. ## Connecting an AI agent to your SaaS data with MCP URL: https://verdantstack.dev/docs/mcp-server-for-ai-agents/ How to point any MCP host at the read-only MCP server every kit ships: the four tools it exposes over the service layer, the client config, the credential each kit needs, and why the surface is reads-only and dependency-free. ## Using Cursor with VerdantStack URL: https://verdantstack.dev/docs/cursor-with-verdantstack/ How to use Cursor with a VerdantStack starter kit: the same three-track layout seen through Cursor's editor workflow, including which generated changes to review against the audit log and tenancy model before shipping. ## Changelog URL: https://verdantstack.dev/changelog/ Every dated release across all three kits, newest first, grouped by track. Generated at build time from each kit's CHANGELOG.md, with a gate that fails the build if the rendered totals disagree with those files. ## Pricing URL: https://verdantstack.dev/pricing/ Every price in one place. Kits, one-time each: Multi-tenant SvelteKit Starter $79 (SQLite / Cloudflare D1), SvelteKit + Supabase Starter $99, SvelteKit + Postgres Starter $79. Each licence is single-seat and covers unlimited projects, with lifetime updates and lifetime standard support and a 30-day refund. Deployment service, fixed-price and fixed-scope: $149 reference deploy (Cloudflare Pages plus Postgres or D1), $299 alternate platform (Vercel, Railway, Fly.io, Netlify or Docker-only), $499 deploy and harden (TLS, sized and documented connection pooling, optional Postgres row-level security, a written backup and restore procedure, CI running the starter's own test suite). ## Privacy URL: https://verdantstack.dev/privacy/ What this site collects, column by column: no cookies, no third-party requests, no persistent identifier. Click events are recorded first-party at /api/event with a salted, daily-rotating IP hash; the IP itself is never stored. ## Deployment service URL: https://verdantstack.dev/services/ Fixed-price, fixed-scope deployment for SvelteKit SaaS starters. Three tiers: T1 $149 reference deploy (Cloudflare Pages + Postgres or D1, the path we run ourselves), T2 $299 alternate platform (Vercel, Railway, Fly.io, Netlify, Docker-only), T3 $499 deploy and harden (TLS, pooling sized and documented, optional Postgres RLS, written backup and restore procedure, CI running the starter's own test suite). Process: written scope and fixed price before anything starts; the client grants access to accounts it owns; pauses at three confirmation points; the deliverable is a written runbook plus a 5-day acceptance window, then 14 days of written support with a 48-hour target. No calls, ever. The brand is the counterparty and no personal identity is disclosed; the written, verifiable deliverable is the trust mechanism. No client count is stated because the service has no clients yet. ## Contact URL: https://verdantstack.dev/contact/ Contact form taking name, email, subject and message, stored in our own database with no third party in the path.