# VerdantStack — Full Documentation for AI Agents > Production-grade developer starters for the parts of software products nobody demos: multi-tenancy, seat billing, role-based access, audit logging. ## About VerdantStack builds production-grade starting points for B2B SaaS foundations. Our first product is a multi-tenant SvelteKit starter that implements organizations, invitations, role-based access control, seat-based billing, and an append-only audit log — typed end to end, tested where it hurts. We believe the "unglamorous core" of a SaaS product (tenancy, licensing, billing, compliance) is where most teams spend months rebuilding the same patterns. Our starters ship that layer done properly so you can focus on what makes your product unique. ## Products ### All products (index) URL: https://verdantstack-site.pages.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-site.pages.dev/products/multi-tenant-sveltekit-starter/ Repository: https://github.com/verdantstack/multi-tenant-sveltekit-starter Status: v0.2.2 — 77 automated tests, CI-verified builds 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 (77 tests against :memory: databases) - CI: GitHub Actions - 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-site.pages.dev/products/multi-tenant-sveltekit-starter/ # Buyers then run: npm install npm run dev # http://localhost:5173 npm test # vitest suite (77 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-site.pages.dev/products/sveltekit-supabase-starter/ Repository: https://github.com/verdantstack/sveltekit-supabase-starter Status: v0.2.1 — 75 automated tests, CI-verified builds License: source-available to buyers (EULA); not open source A production-grade 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 (75 tests against an in-memory fake Supabase client) - Deployment: Any Node.js host **Pricing:** - Early-bird: $79 - Standard: $149 - One license, one developer, lifetime updates + lifetime standard support included --- ## Live Demos Both 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://verdantstack-demo-a.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://verdantstack-demo-b.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`). --- ## Comparisons & Guides ### Documentation Index URL: https://verdantstack-site.pages.dev/docs/ Hub page listing product documentation, shared guides, comparisons, and the license agreement. ### SvelteKit vs Next.js for SaaS URL: https://verdantstack-site.pages.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-site.pages.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-site.pages.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-site.pages.dev/comparison/sveltekit-starter-vs-cmsaasstarter/ Feature-by-feature comparison of VerdantStack Multi-tenant SvelteKit Starter vs CMSaasStarter (2,357★ Supabase starter). Covers auth, tenancy, RBAC, billing, audit, database, and deployment. ### SvelteKit SaaS Boilerplate — What You Actually Need URL: https://verdantstack-site.pages.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-site.pages.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. ### How to Build Multi-Tenant SaaS with SvelteKit URL: https://verdantstack-site.pages.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-site.pages.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-site.pages.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-site.pages.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-site.pages.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-site.pages.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-site.pages.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-site.pages.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-site.pages.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-site.pages.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-site.pages.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-site.pages.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-site.pages.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-site.pages.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-site.pages.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-site.pages.dev/products/multi-tenant-sveltekit-starter/docs/sveltekit-testing-vitest/ Unit tests, integration tests, and HTTP-level patterns from a 77-test suite covering auth, RBAC, invites, and rate limiting. ### SQLite for Production SaaS URL: https://verdantstack-site.pages.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-site.pages.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-site.pages.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-site.pages.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-site.pages.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-site.pages.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-site.pages.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-site.pages.dev/products/sveltekit-supabase-starter/docs/testing/ Six Vitest suites (75 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-site.pages.dev/products/sveltekit-supabase-starter/docs/versioning/ Semantic Versioning and Keep a Changelog for the Supabase starter; version history and release process. --- ## 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/ # Repo guard, CI helpers └── .github/workflows/ci.yml # GitHub Actions CI ``` --- ## Contact - 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` - Product pages (buy links): https://verdantstack-site.pages.dev/products/