Documentation
Technical guide to the starter: architecture, modules, security, and how to launch a new SaaS on this foundation.
Introduction
Nimbus is a production-ready SaaS starter. It includes authentication, roles, an admin panel, toggleable modules, teams, billing, credits, an AI assistant, notifications and legal pages — all with light/dark mode and ES/EN internationalization.
The goal is to launch new SaaS products without starting from scratch: clone the project, adjust branding in Administration → Settings, disable the modules you don't need, and build your business entity following the blueprint module (Projects).
Tech stack
- React 19 + TypeScript + Vite 7 (TanStack Start, SSR)
- Tailwind CSS v4 with semantic tokens + shadcn/ui
- Backend: Lovable Cloud (Postgres database, auth, storage, RLS)
- TanStack Router (file-based routes) + TanStack Query (data)
- AI: Lovable AI Gateway (no own keys required)
- Tests: Vitest · Icons: lucide-react · Toasts: sonner
Routes live in src/routes. Signed-in pages are under src/routes/_authenticated/ (a single auth boundary). Public pages (/, /pricing, /privacy, /terms, /docs) share PublicLayout.
Authentication & roles
Sign in with email/password and Google. On signup, a trigger creates the profile and assigns the user role. Roles live only in the user_roles table and are checked with the has_role() function — never in user-editable metadata.
Every table has Row Level Security (RLS) enabled: each user can only read and write their own data. Privileged actions (suspending users, changing roles, adjusting credits) go through server functions that verify the admin role server-side and are recorded in the audit log.
Toggleable modules
The heart of the starter: every product feature (signup, onboarding, projects, teams, billing, AI, support, announcements, notifications, API keys) is a module toggled from Administration → Modules, without touching code.
The module registry lives in src/lib/modules.ts (icon, category, routes). The database only stores on/off state. The sidebar hides disabled modules and their routes show “Feature unavailable” (admins always keep access). The signup module is enforced at the database level: when off, nobody can register.
// Adding a new module: // 1. Row in app_modules (migration) // 2. Entry in MODULES in src/lib/modules.ts // 3. Done: the shell hides/blocks it automatically
Blueprint entity (CRUD)
Projects is the example entity to clone for your business. It includes: a table with search, filters, sorting and pagination; multi-select with bulk actions; CSV export; a create/edit drawer with validation; a detail view with tabs (summary, activity, comments).
Activity is written automatically by a database trigger. Pure logic (filter, sort, CSV) lives in src/lib/projects.ts with unit tests — replicate this structure for every new entity.
Teams (multi-tenancy)
Users can create organizations, invite members by email with a role (member/admin) and manage the team. Invitations are accepted from the Teams page and generate an in-app notification.
Security uses SECURITY DEFINER functions (create_organization, accept_invitation, org_member_profiles) and RLS policies with org_role()/is_org_member(), avoiding recursive policies and keeping emails server-side.
Billing & credits
Plans are edited from Administration → Plans and the public /pricing page reads them in real time (monthly/yearly toggle, comparison table, FAQ). Users have a credit balance that admins can adjust with a reason (everything is audited).
Payment gateway keys (Stripe, Polar, PayPal) are configured in Administration → Integrations. Only admins can see them; they are never exposed to the browser or public pages.
AI module
The assistant (/ai) offers chats with persistent history. Each message checks the user's balance first and charges 1 credit on reply; without balance, it notifies and points to Billing. Chats are private via RLS.
The model call always happens server-side (src/lib/ai.functions.ts) through the Lovable AI Gateway — no keys in the browser. Your own provider keys (Claude, OpenAI, Gemini, Grok, Deepseek) are stored in Integrations for future modules.
Admin panel
- Overview: users, MRR, signups, churn and charts
- Users: list, filters, detail, suspend, change role, adjust credits
- Organizations, Plans (CRUD), Credits, Payments & revenue
- Audit: every privileged action is logged
- Modules, Feature flags, Global announcements (bilingual, dated)
- Support tickets, Email templates, Integrations
- System settings: name, logo, emails, maintenance mode
- System health
Access requires the admin role (has_role guard). List pages use the config-driven AdminCrud component (src/components/admin/kit.tsx): define fields and columns, and get table + dialog + validation + audit for free.
i18n & theme
All UI strings live in src/lib/i18n.tsx, in Spanish and English. Golden rule: every new string is added in both languages. Users switch language from the top bar selector.
The light/dark theme is a class on <html> applied before first paint (no flash). Never hardcode colors in components: use semantic tokens (bg-card, text-muted-foreground, bg-primary…) so both themes work automatically.
Security & privacy
- RLS enabled on every table; service keys only on the server
- User API keys: only the SHA-256 hash + prefix is stored; plaintext is shown once
- Avatars in a private bucket, max 2 MB, paths scoped to the user
- Notifications created only by triggers (no client inserts)
- GDPR export: Settings → Export my data (full JSON)
- Account deletion with confirmation, server-side
- Cookie banner and legal pages (/privacy, /terms)
Launching a new SaaS
- 1. Clone the project and change name/logo in Administration → Settings
- 2. Turn off the modules you don't need in Administration → Modules
- 3. Clone the blueprint entity (Projects) with your data model
- 4. Edit plans in Administration → Plans (reflected on /pricing)
- 5. Configure your gateway in Administration → Integrations
- 6. Review the legal texts (/privacy, /terms) with your real data
- 7. Publish and connect your domain