SaaS Starter Example
Build a complete SaaS application with authentication, subscriptions, and team management.
Overview
This example creates a production-ready SaaS with:
- User authentication (JWT)
- Stripe subscriptions
- Team/organization support
- Admin dashboard
- User settings
- Email notifications
Create the Project
npx autodeploybase init my-saas \
--framework next \
--archetype saas \
--database postgresql \
--plugins payments-stripe,email
cd my-saas
Project Structure
my-saas/
├── prisma/
│ └── schema.prisma
├── src/
│ ├── app/
│ │ ├── (auth)/
│ │ │ ├── login/
│ │ │ └── register/
│ │ ├── (dashboard)/
│ │ │ ├── dashboard/
│ │ │ ├── settings/
│ │ │ └── billing/
│ │ ├── admin/
│ │ │ ├── users/
│ │ │ └── settings/
│ │ └── api/
│ │ ├── auth/
│ │ ├── billing/
│ │ └── webhooks/
│ ├── components/
│ └── lib/
├── .env.example
└── autodeploy.config.json
Configuration
Environment Variables
.env
# Database
DATABASE_URL="postgresql://postgres:password@localhost:5432/my_saas"
# Auth
JWT_SECRET="your-secure-secret-at-least-32-chars"
# Stripe
STRIPE_SECRET_KEY="sk_test_..."
STRIPE_PUBLISHABLE_KEY="pk_test_..."
STRIPE_WEBHOOK_SECRET="whsec_..."
# Email
EMAIL_PROVIDER="resend"
RESEND_API_KEY="re_..."
# App
NEXT_PUBLIC_APP_URL="http://localhost:3000"
Stripe Products
Create products in Stripe Dashboard:
- Starter - $9/month
- Pro - $29/month
- Enterprise - $99/month
Add price IDs to config:
autodeploy.config.json
{
"plugins": {
"payments-stripe": {
"settings": {
"products": [
{ "name": "Starter", "priceId": "price_xxx" },
{ "name": "Pro", "priceId": "price_yyy" },
{ "name": "Enterprise", "priceId": "price_zzz" }
]
}
}
}
}
Setup
# Install dependencies
npm install
# Set up database
npx prisma generate
npx prisma migrate dev --name init
npx prisma db seed
# Start development
npm run dev
Features Walkthrough
1. User Registration
Users can register with email and password:
app/(auth)/register/page.tsx
import { RegisterForm } from '@/components/auth/RegisterForm';
export default function RegisterPage() {
return (
<div className="auth-page">
<h1>Create Account</h1>
<RegisterForm />
</div>
);
}
2. Subscription Management
Users can upgrade/downgrade their plan:
app/(dashboard)/billing/page.tsx
import { PricingTable } from '@/components/billing/PricingTable';
import { CurrentPlan } from '@/components/billing/CurrentPlan';
import { getUser } from '@/lib/auth';
export default async function BillingPage() {
const user = await getUser();
return (
<div>
<h1>Billing</h1>
<CurrentPlan subscription={user.subscription} />
<PricingTable currentPlan={user.subscription?.plan} />
</div>
);
}
3. Team Management
Pro and Enterprise users can create teams:
app/(dashboard)/team/page.tsx
import { TeamMembers } from '@/components/team/TeamMembers';
import { InviteForm } from '@/components/team/InviteForm';
export default async function TeamPage() {
return (
<div>
<h1>Team</h1>
<InviteForm />
<TeamMembers />
</div>
);
}
4. Admin Dashboard
Admins can manage users and settings:
app/admin/page.tsx
import { AdminStats } from '@/components/admin/AdminStats';
import { RecentUsers } from '@/components/admin/RecentUsers';
import { RevenueChart } from '@/components/admin/RevenueChart';
export default async function AdminDashboard() {
return (
<div className="grid gap-6">
<AdminStats />
<div className="grid grid-cols-2 gap-6">
<RecentUsers />
<RevenueChart />
</div>
</div>
);
}
Database Schema
prisma/schema.prisma
model User {
id String @id @default(cuid())
email String @unique
password String
name String?
role Role @default(USER)
subscription Subscription?
team Team? @relation("TeamMembers")
teamId String?
ownedTeam Team? @relation("TeamOwner")
createdAt DateTime @default(now())
}
model Subscription {
id String @id @default(cuid())
userId String @unique
user User @relation(fields: [userId], references: [id])
stripeCustomerId String @unique
stripePriceId String
status SubscriptionStatus
currentPeriodEnd DateTime
}
model Team {
id String @id @default(cuid())
name String
ownerId String @unique
owner User @relation("TeamOwner", fields: [ownerId], references: [id])
members User[] @relation("TeamMembers")
}
Customization
Add Features
# Add analytics
npx autodeploybase add analytics
# Add file uploads
npx autodeploybase add file-storage
Customize Theme
app/globals.css
:root {
--primary: #6366f1;
--primary-foreground: #ffffff;
--background: #ffffff;
--foreground: #1a1a1a;
}
.dark {
--background: #1a1a1a;
--foreground: #ffffff;
}
Add Pages
app/(dashboard)/analytics/page.tsx
export default function AnalyticsPage() {
return (
<div>
<h1>Analytics</h1>
{/* Your analytics content */}
</div>
);
}
Deployment
Vercel
vercel
Set environment variables in Vercel dashboard.
Docker
docker-compose up -d
Next Steps
- Configure Stripe webhooks for subscription events
- Add custom pricing page with your plans
- Implement team features for collaboration
- Add email templates for notifications
- Set up monitoring with your preferred tool