Launch your startup in days, not weeks. A production-ready Next.js 15 SaaS boilerplate with authentication, payments, email, and more.
- Authentication - Google OAuth and magic link email authentication with NextAuth.js
- Payments - Complete Stripe integration with checkout, subscriptions, and customer portal
- Database - MongoDB with Mongoose ODM (Supabase support included)
- Email - Transactional emails with Resend (Mailgun alternative available)
- Rate Limiting - Upstash Redis-based rate limiting for API protection
- UI Components - Pre-built components with Tailwind CSS and DaisyUI
- Blog - Built-in blog system with markdown support
- SEO - Automatic sitemap generation with next-sitemap
- Customer Support - Crisp chat integration
- Analytics - Plausible Analytics integration
- Type Safety - Full TypeScript support throughout
- Framework: Next.js 15 with App Router and Turbopack
- Language: TypeScript 5
- Styling: Tailwind CSS 3, DaisyUI 5
- Database: MongoDB with Mongoose
- Authentication: NextAuth.js 4 with MongoDB adapter
- Payments: Stripe
- Email: Resend
- Rate Limiting: Upstash Redis
- Deployment: Vercel-ready
- Node.js 20+ installed
- MongoDB database (local or MongoDB Atlas)
- Stripe account for payments
- Google OAuth credentials
- Resend account for emails
- Clone the repository:
git clone <your-repo-url>
cd shipfast- Install dependencies:
npm install- Set up environment variables:
cp .env.example .envEdit .env and add your credentials (see SETUP.md for detailed instructions).
- Run the development server:
npm run dev- Open http://localhost:3000 in your browser.
shipfast/
├── app/ # Next.js 15 App Router
│ ├── api/ # API routes
│ │ ├── auth/ # NextAuth endpoints
│ │ └── stripe/ # Stripe checkout & webhooks
│ ├── blog/ # Blog pages
│ └── page.tsx # Landing page
├── components/ # React components
│ ├── blog/ # Blog-specific components
│ ├── ButtonCheckout.tsx
│ ├── Pricing.tsx
│ └── ...
├── libs/ # Utility libraries
│ ├── mongo.ts # MongoDB client
│ ├── mongoose.ts # Mongoose connection
│ ├── next-auth.ts # Auth configuration
│ ├── stripe.ts # Stripe utilities
│ └── resend.ts # Email utilities
├── models/ # Mongoose models
│ ├── User.ts
│ ├── Account.ts
│ └── Session.ts
├── types/ # TypeScript type definitions
├── public/ # Static assets
├── config.ts # Application configuration
└── middleware.ts # Next.js middleware
Required environment variables:
# App
NEXT_PUBLIC_APP_URL=http://localhost:3000
# NextAuth
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-secret-key-min-15-chars
# Google OAuth
GOOGLE_ID=your-google-client-id
GOOGLE_SECRET=your-google-client-secret
# MongoDB
MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/database
# Stripe
STRIPE_SECRET_KEY=sk_test_your_stripe_secret_key
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_your_stripe_publishable_key
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret
# Resend
RESEND_API_KEY=re_your_resend_api_key
# Upstash Redis
UPSTASH_REDIS_REST_URL=your-upstash-redis-url
UPSTASH_REDIS_REST_TOKEN=your-upstash-redis-tokenSee SETUP.md for detailed setup instructions for each service.
npm run dev- Start development server with Turbopacknpm run build- Build for productionnpm start- Start production servernpm run lint- Run ESLint
The main configuration is in config.ts:
const config = {
appName: "ShipFast",
appDescription: "Launch your startup in days, not weeks",
domainName: "shipfast.com",
stripe: {
plans: [...], // Define your pricing plans
},
colors: {
theme: "", // Auto light/dark
main: "#FFBE18", // Primary color
},
// ... more options
};Edit the stripe.plans array in config.ts:
stripe: {
plans: [
{
priceId: "price_123",
name: "Starter",
price: 19,
features: [
{ name: "Feature 1" },
{ name: "Feature 2" },
],
},
],
}- Google OAuth sign-in
- Magic link email authentication
- Secure session management with MongoDB
- Protected routes via middleware
- One-time payments
- Subscription management
- Customer portal
- Webhook handling for automated fulfillment
- Promo code support
API endpoints are protected with Upstash Redis rate limiting:
import { rateLimit } from "@/libs/security";
// Apply rate limiting
const { success } = await rateLimit.limit(identifier);
if (!success) return NextResponse.json({ error: "Too many requests" });Transactional emails with Resend:
import { resend } from "@/libs/resend";
await resend.emails.send({
from: config.mailgun.fromNoReply,
to: email,
subject: "Welcome!",
html: emailTemplate,
});- Push your code to GitHub
- Import repository in Vercel
- Add environment variables
- Deploy
After deployment, configure your Stripe webhook:
- Go to Stripe Dashboard > Developers > Webhooks
- Add endpoint:
https://yourdomain.com/api/stripe/webhook - Select events:
checkout.session.completed,customer.subscription.updated,customer.subscription.deleted - Copy webhook secret to
STRIPE_WEBHOOK_SECRET
- FEATURES.md - Detailed feature documentation
- SETUP.md - Step-by-step setup guide for all services
- ARCHITECTURE.md - Project architecture and design decisions
- CHANGELOG.md - Version history
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow TypeScript best practices
- Use existing component patterns
- Update documentation when adding features
- Test payments in Stripe test mode
- Keep dependencies up to date
- Email: support@shipfast.com
- Documentation: Full docs
- Issues: GitHub Issues
This project is licensed under the MIT License - see the LICENSE file for details.
Built with:
Made with care for indie hackers and startup founders.